Which implementation of "set/get" member functions is better? Please help.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Me

    Which implementation of "set/get" member functions is better? Please help.

    Hi, I would like learn from people with experience in C++, which of the
    following styles of way to construct "get/set" member functions would be the
    best in terms of usability, speed, et cetera.

    The following class with be used as an example:
    class MyClass {
    public:
    // member function would go here.
    private:
    int data_;
    };

    Way #1:
    int getData() const;
    void setData(const int);

    Way #2:
    int getData() const;
    int setData(int); // returns data_

    Way #3:
    int data() const;
    void data(int);

    Way #4:
    int data() const;
    int data(int); // returns data_

    My preference would be to use the fourth way, but I would like to know which
    of the ways listed should be prefered or if there are any other ways that
    should have been included.

    Also, I notice that people who are into OOA and OOD seem to use getBlah, and
    setBlah. Why is this the case? Were most of these individuals influened by
    one source and that is why they all share the same way of doing it?

    Thanks.


  • John Harrison

    #2
    Re: Which implementation of "set/get" member functions is better? Please help.


    "Me" <alexa_manning@ rogers.com> wrote in message
    news:rfZ%a.2327 84$rsJ.221964@n ews04.bloor.is. net.cable.roger s.com...[color=blue]
    > Hi, I would like learn from people with experience in C++, which of the
    > following styles of way to construct "get/set" member functions would be[/color]
    the[color=blue]
    > best in terms of usability, speed, et cetera.
    >
    > The following class with be used as an example:
    > class MyClass {
    > public:
    > // member function would go here.
    > private:
    > int data_;
    > };
    >
    > Way #1:
    > int getData() const;
    > void setData(const int);
    >
    > Way #2:
    > int getData() const;
    > int setData(int); // returns data_
    >
    > Way #3:
    > int data() const;
    > void data(int);
    >
    > Way #4:
    > int data() const;
    > int data(int); // returns data_
    >
    > My preference would be to use the fourth way, but I would like to know[/color]
    which[color=blue]
    > of the ways listed should be prefered or if there are any other ways that
    > should have been included.
    >
    > Also, I notice that people who are into OOA and OOD seem to use getBlah,[/color]
    and[color=blue]
    > setBlah. Why is this the case? Were most of these individuals influened by
    > one source and that is why they all share the same way of doing it?
    >
    > Thanks.
    >
    >[/color]

    A fifth way is

    int& data();
    int data() const;

    but I don't like it, returning a reference more or less commits you to using
    a member variable internally. Personally I'd use your first method. Get and
    set are different enough that they deserve different names. I don't see the
    need to return the previous value from set, if I needed that I'd call get
    before set. Again this seems a matter of clarity to me, which should be your
    main consideration, not speed.

    john


    Comment

    • Gianni Mariani

      #3
      Re: Which implementation of &quot;set/get&quot; member functions is better?Please help.

      John Harrison wrote:[color=blue]
      > "Me" <alexa_manning@ rogers.com> wrote in message
      > news:rfZ%a.2327 84$rsJ.221964@n ews04.bloor.is. net.cable.roger s.com...
      >[color=green]
      >>Hi, I would like learn from people with experience in C++, which of the
      >>following styles of way to construct "get/set" member functions would be[/color]
      >
      > the
      >[color=green]
      >>best in terms of usability, speed, et cetera.
      >>
      >>The following class with be used as an example:
      >>class MyClass {
      >>public:
      >> // member function would go here.
      >>private:
      >> int data_;
      >>};
      >>
      >>Way #1:
      >>int getData() const;
      >>void setData(const int);
      >>
      >>Way #2:
      >>int getData() const;
      >>int setData(int); // returns data_
      >>
      >>Way #3:
      >>int data() const;
      >>void data(int);
      >>
      >>Way #4:
      >>int data() const;
      >>int data(int); // returns data_
      >>
      >>My preference would be to use the fourth way, but I would like to know[/color]
      >
      > which
      >[color=green]
      >>of the ways listed should be prefered or if there are any other ways that
      >>should have been included.
      >>
      >>Also, I notice that people who are into OOA and OOD seem to use getBlah,[/color]
      >
      > and
      >[color=green]
      >>setBlah. Why is this the case? Were most of these individuals influened by
      >>one source and that is why they all share the same way of doing it?
      >>
      >>Thanks.
      >>
      >>[/color]
      >
      >
      > A fifth way is
      >
      > int& data();
      > int data() const;
      >
      > but I don't like it, returning a reference more or less commits you to using
      > a member variable internally. Personally I'd use your first method. Get and
      > set are different enough that they deserve different names. I don't see the
      > need to return the previous value from set, if I needed that I'd call get
      > before set. Again this seems a matter of clarity to me, which should be your
      > main consideration, not speed.
      >[/color]

      And there is a 6th way which is a variant of the 5th.

      AccessorReferen ce<data_attribu tes> data();
      const AccessorReferen ce<data_attribu tes> data() const;

      Where an object of type AccessorReferen ce<data_attribu tes> has
      assignment and cast operators that do what you expect.

      It solves the problem you describe "commits you to using a member
      variable". This allows you to have a single interface to get and set a
      variable regardless if it's a member variable or somthing different.

      I've used this technique when you might also have a variant on HOW you
      get or set the data.

      e.g.

      obj.data()(Scop ingName) = 1;

      obj.data()(NotT hrow) = 1;


      Comment

      • Icosahedron

        #4
        Re: Which implementation of &quot;set/get&quot; member functions is better? Please help.


        "Me" <alexa_manning@ rogers.com> wrote in message
        news:rfZ%a.2327 84$rsJ.221964@n ews04.bloor.is. net.cable.roger s.com...[color=blue]
        > Hi, I would like learn from people with experience in C++, which of the
        > following styles of way to construct "get/set" member functions would be[/color]
        the[color=blue]
        > best in terms of usability, speed, et cetera.
        >
        > The following class with be used as an example:
        > class MyClass {
        > public:
        > // member function would go here.
        > private:
        > int data_;
        > };
        >
        > Way #1:
        > int getData() const;
        > void setData(const int);
        >
        > Way #2:
        > int getData() const;
        > int setData(int); // returns data_
        >
        > Way #3:
        > int data() const;
        > void data(int);
        >[/color]

        My preference is for #3. This the way I do it in my personal code, though
        at work we use #1.
        [color=blue]
        > Also, I notice that people who are into OOA and OOD seem to use getBlah,[/color]
        and[color=blue]
        > setBlah. Why is this the case? Were most of these individuals influened by
        > one source and that is why they all share the same way of doing it?
        >[/color]

        Maybe because in OOA and OOD circles, being language neutral, they can't
        assume that parameters are taken into account for polymorphism? Just a
        guess.

        Jay


        Comment

        • Corno

          #5
          Re: Which implementation of &quot;set/get&quot; member functions is better? Please help.


          "Me" <alexa_manning@ rogers.com> wrote in message
          news:rfZ%a.2327 84$rsJ.221964@n ews04.bloor.is. net.cable.roger s.com...[color=blue]
          > Hi, I would like learn from people with experience in C++, which of the
          > following styles of way to construct "get/set" member functions would be[/color]
          the[color=blue]
          > best in terms of usability, speed, et cetera.
          >
          > The following class with be used as an example:
          > class MyClass {
          > public:
          > // member function would go here.
          > private:
          > int data_;
          > };
          >
          > Way #1:
          > int getData() const;
          > void setData(const int);
          >
          > Way #2:
          > int getData() const;
          > int setData(int); // returns data_
          >
          > Way #3:
          > int data() const;
          > void data(int);
          >
          > Way #4:
          > int data() const;
          > int data(int); // returns data_
          >[/color]
          And there is a #0 way.... not using them at all (or at least very rarely).
          Sometimes a class of mine has a set function, sometimes a get function but
          never the combination of the both. Rethink your design and see if you cannot
          let the owning class do the things that need to be done with it's member
          variables. It strongly improves the OO.

          Corno


          Comment

          • John Harrison

            #6
            Re: Which implementation of &quot;set/get&quot; member functions is better? Please help.

            > >[color=blue][color=green]
            > > A fifth way is
            > >
            > > int& data();
            > > int data() const;
            > >[/color][/color]
            [snip]
            [color=blue]
            >
            > And there is a 6th way which is a variant of the 5th.
            >
            > AccessorReferen ce<data_attribu tes> data();
            > const AccessorReferen ce<data_attribu tes> data() const;
            >
            > Where an object of type AccessorReferen ce<data_attribu tes> has
            > assignment and cast operators that do what you expect.
            >
            > It solves the problem you describe "commits you to using a member
            > variable". This allows you to have a single interface to get and set a
            > variable regardless if it's a member variable or somthing different.
            >
            > I've used this technique when you might also have a variant on HOW you
            > get or set the data.
            >
            > e.g.
            >
            > obj.data()(Scop ingName) = 1;
            >
            > obj.data()(NotT hrow) = 1;
            >[/color]

            Proxy classes in other words. Perhaps the OP would benefit from a short
            example? I think s/he would be interested.

            john


            Comment

            • Me

              #7
              Re: Which implementation of &quot;set/get&quot; member functions is better? Please help.

              Hi, I must admit that I don't understand the "proxy class" that was
              mentioned. Would you mind explaining it? It seems that using it would be
              inefficient compared to the other methods, but since I don't know anything
              of proxy classes, perhaps it doesn't.

              Thanks for the alternatives, both of you.

              "John Harrison" <john_andronicu s@hotmail.com> wrote in message
              news:bhq3bh$1vs lt$1@ID-196037.news.uni-berlin.de...[color=blue][color=green][color=darkred]
              > > >
              > > > A fifth way is
              > > >
              > > > int& data();
              > > > int data() const;
              > > >[/color][/color]
              > [snip]
              >[color=green]
              > >
              > > And there is a 6th way which is a variant of the 5th.
              > >
              > > AccessorReferen ce<data_attribu tes> data();
              > > const AccessorReferen ce<data_attribu tes> data() const;
              > >
              > > Where an object of type AccessorReferen ce<data_attribu tes> has
              > > assignment and cast operators that do what you expect.
              > >
              > > It solves the problem you describe "commits you to using a member
              > > variable". This allows you to have a single interface to get and set a
              > > variable regardless if it's a member variable or somthing different.
              > >
              > > I've used this technique when you might also have a variant on HOW you
              > > get or set the data.
              > >
              > > e.g.
              > >
              > > obj.data()(Scop ingName) = 1;
              > >
              > > obj.data()(NotT hrow) = 1;
              > >[/color]
              >
              > Proxy classes in other words. Perhaps the OP would benefit from a short
              > example? I think s/he would be interested.
              >
              > john
              >
              >[/color]


              Comment

              • Me

                #8
                Re: Which implementation of &quot;set/get&quot; member functions is better? Please help.

                It's interesting to know that your job requires the first way. I didn't
                expect to find things like this out.

                You're explanation for the reason why OOA/OOD people use get/set in the
                names makes sense. I know that most of them know LISP, perhaps that doesn't
                have overloading?

                Thanks for the feedback.
                "Icosahedro n" <noone@nowhere. com> wrote in message
                news:Ug%%a.1034 91$3o3.7231855@ bgtnsc05-news.ops.worldn et.att.net...[color=blue]
                >
                > "Me" <alexa_manning@ rogers.com> wrote in message
                > news:rfZ%a.2327 84$rsJ.221964@n ews04.bloor.is. net.cable.roger s.com...[color=green]
                > > Hi, I would like learn from people with experience in C++, which of the
                > > following styles of way to construct "get/set" member functions would be[/color]
                > the[color=green]
                > > best in terms of usability, speed, et cetera.
                > >
                > > The following class with be used as an example:
                > > class MyClass {
                > > public:
                > > // member function would go here.
                > > private:
                > > int data_;
                > > };
                > >
                > > Way #1:
                > > int getData() const;
                > > void setData(const int);
                > >
                > > Way #2:
                > > int getData() const;
                > > int setData(int); // returns data_
                > >
                > > Way #3:
                > > int data() const;
                > > void data(int);
                > >[/color]
                >
                > My preference is for #3. This the way I do it in my personal code, though
                > at work we use #1.
                >[color=green]
                > > Also, I notice that people who are into OOA and OOD seem to use getBlah,[/color]
                > and[color=green]
                > > setBlah. Why is this the case? Were most of these individuals influened[/color][/color]
                by[color=blue][color=green]
                > > one source and that is why they all share the same way of doing it?
                > >[/color]
                >
                > Maybe because in OOA and OOD circles, being language neutral, they can't
                > assume that parameters are taken into account for polymorphism? Just a
                > guess.
                >
                > Jay
                >
                >[/color]


                Comment

                • Attila Feher

                  #9
                  Re: Which implementation of &quot;set/get&quot; member functions is better? Please help.

                  John Harrison wrote:
                  [SNIP][color=blue]
                  > A fifth way is
                  >
                  > int& data();
                  > int data() const;
                  >
                  > but I don't like it, returning a reference more or less commits you
                  > to using a member variable internally.[/color]
                  [SNIP]

                  Actually in the first version you might use some sort of proxy object -
                  instead of the int. That you may even return by value (contains a pointer
                  or reference). However IMHO ANY kind of getter/setter is bad. If something
                  contains only publicly accassible unchecked variables: make it a struct. If
                  not: make it something sensible. I can believe that a setVolume and
                  getVolume function pair is sensible, but they would certainly not
                  take/return int, but something called Volume...

                  Attila


                  Comment

                  • Gianni Mariani

                    #10
                    Re: Which implementation of &quot;set/get&quot; member functions is better?Please help.

                    Me wrote:[color=blue]
                    > Hi, I must admit that I don't understand the "proxy class" that was
                    > mentioned. Would you mind explaining it? It seems that using it would be
                    > inefficient compared to the other methods, but since I don't know anything
                    > of proxy classes, perhaps it doesn't.
                    >
                    > Thanks for the alternatives, both of you.
                    >[/color]

                    Who invented the name "proxy class" ?


                    So effienciency need not necessarily be bad. If your proxy class
                    contructor and accessors are simple enough, the compiler may optimize
                    them away making it just as fast as anything else.

                    Just say you had a class with an extreme number of attributes and they
                    all did basically the same thing but if any of them was changed, you
                    needed to perform some post processing )e.g. recompute a checksum or
                    inform a GUI object of the change, write the change to disk, or perhaps
                    make a "transactio n" where you change a number of attributes at once but
                    you wanted to make the change to be made atomically yet you wanted to
                    hide all of this and make it look just like getters and setters.

                    I created a quick chunk of test code that implements the
                    lock/transaction scenario. In this case we're using the property of how
                    C++ temporary objects are created and destroyed to our advantage. Hence
                    any SINGLE C++ expression is transaction safe because temporary objects
                    are the last thing to be destroyed when executing an expression.
                    Actually, if you decide to pollute your code with nasty Proxy objects
                    you could extend the transaction safety beyond a single expression.

                    Note that the example below DOES NOT TAKE INTO ACCOUNT issues when you
                    have 2 or more lockable objects. The order in which you take a mutex is
                    extremely important in avoiding deadlock.

                    I've never used this paradigm for managing tranactions and I'm not sure
                    that it makes sense to do it like this because writing expressions and
                    transaction semantics are not genrally combinable concepts. Having said
                    that, I'm sure there are some cases where this paradigm may work
                    perfectly (like reading/writing to shared memory). Also, with a little
                    more work, you could actually make rollback on exception functional
                    which IS truly cool.

                    As for efficiency, as I alluded earlier, the compiler should be able to
                    inline and remove most of the code that does nothing. Hence from an
                    efficiency standpoint, this is about as efficient as anything you could
                    write by hand.

                    This is just an example of how you can use a proxy. There are so many
                    more uses. I've used variations on this for factory accessors and
                    shared memory accessors but they didn't seem to be appropriate examples
                    given the OP question.

                    One last point, there is nothing stopping you from using methods GetData
                    and SetData with proxy classes. My original response to John was just a
                    clarification on the theme he described.


                    #include <iostream>

                    // demo lock - does nothing like locking just yells
                    struct MutexType
                    {
                    int m_lock_count;

                    MutexType()
                    : m_lock_count( 0 )
                    {}

                    void TakeLock()
                    {
                    if ( m_lock_count ++ ) return;
                    std::cout << "lock is taken\n";
                    }

                    void ReleaseLock()
                    {
                    if ( -- m_lock_count ) return;
                    std::cout << "lock is released\n";
                    }
                    };

                    struct Lock
                    {
                    Lock( MutexType & i_mutex )
                    : m_mutex( & i_mutex )
                    {
                    m_mutex->TakeLock();
                    }

                    ~Lock()
                    {
                    m_mutex->ReleaseLock( );
                    }

                    MutexType * m_mutex;
                    };

                    template<typena me Type> class Proxy
                    {
                    public:
                    Proxy( Type & value, MutexType & i_mutex )
                    : m_value( value ),
                    m_lock( i_mutex )
                    {
                    }

                    operator const Type & () const
                    {
                    std::cout << "converted to Type\n";
                    return m_value;
                    }

                    // operator =

                    Proxy & operator= ( const Type & i_val )
                    {
                    std::cout << "= Type\n";
                    m_value = i_val;
                    return * this;
                    }

                    template<typena me RHSType> Proxy & operator= ( const Proxy<RHSType>
                    & i_val )
                    {
                    std::cout << "= Proxy<RHSType>\ n";
                    m_value = i_val.get();
                    return * this;
                    }

                    Proxy & operator= ( const Proxy & i_val )
                    {
                    std::cout << "= Proxy\n";
                    m_value = i_val.get();
                    return * this;
                    }

                    // operator +=

                    Proxy & operator+= ( const Type & i_val )
                    {
                    std::cout << "+= Type\n";
                    m_value += i_val;
                    return * this;
                    }

                    template<typena me RHSType> Proxy & operator+= ( const
                    Proxy<RHSType> & i_val )
                    {
                    std::cout << "+= Proxy<RHSType>\ n";
                    m_value += i_val.get();
                    return * this;
                    }

                    Proxy & operator+= ( const Proxy & i_val )
                    {
                    std::cout << "+= Proxy\n";
                    m_value += i_val.get();
                    return * this;
                    }

                    // operator -=

                    Proxy & operator-= ( const Type & i_val )
                    {
                    std::cout << "-= Type\n";
                    m_value -= i_val;
                    return * this;
                    }

                    template<typena me RHSType> Proxy & operator-= ( const
                    Proxy<RHSType> & i_val )
                    {
                    std::cout << "-= Proxy<RHSType>\ n";
                    m_value -= i_val.get();
                    return * this;
                    }

                    Proxy & operator-= ( const Proxy & i_val )
                    {
                    std::cout << "-= Proxy\n";
                    m_value -= i_val.get();
                    return * this;
                    }

                    // etc for all the operators you want

                    const Type & get() const
                    {
                    return m_value;
                    }

                    Type & m_value;
                    Lock m_lock;

                    };

                    struct BigNastyAttribu teClass
                    {

                    int m_val1;
                    float m_val2;

                    MutexType m_lock;

                    Proxy<int> val1()
                    {
                    return Proxy<int>( m_val1, m_lock );
                    }

                    Proxy<float> val2()
                    {
                    return Proxy<float>( m_val2, m_lock );
                    }

                    };


                    void Tester( BigNastyAttribu teClass & foo )
                    {

                    std::cout << "do 1\n";

                    foo.val2() = 3 + ( foo.val1() += 3 );

                    std::cout << "do 2\n";

                    foo.val2() -= ( foo.val1() += 4 );

                    std::cout << "do 3\n";

                    foo.val2() = 4, foo.val1() += 9;

                    std::cout << "return\n";
                    }

                    int main()
                    {
                    BigNastyAttribu teClass a;

                    Tester( a );
                    }

                    This code spits out:

                    do 1
                    lock is taken
                    += Type
                    converted to Type
                    = Type
                    lock is released
                    do 2
                    lock is taken
                    += Type
                    -= Proxy<RHSType>
                    lock is released
                    do 3
                    lock is taken
                    = Type
                    += Type
                    lock is released
                    return

                    Note how "lock is taken" and "lock is released" neatly wrap assignment
                    and conversion (getter) operations. I hope this helps.

                    Comment

                    • Buster Copley

                      #11
                      Re: Which implementation of &quot;set/get&quot; member functions is better?Please help.

                      Gianni Mariani wrote:[color=blue]
                      > Me wrote:
                      >[color=green]
                      >> Hi, I must admit that I don't understand the "proxy class" that was
                      >> mentioned. Would you mind explaining it? It seems that using it would be
                      >> inefficient compared to the other methods, but since I don't know
                      >> anything
                      >> of proxy classes, perhaps it doesn't.
                      >>
                      >> Thanks for the alternatives, both of you.
                      >>[/color]
                      >
                      > Who invented the name "proxy class" ?[/color]

                      It's not a name, but a description. Look up 'proxy' in the dictionary.
                      If you really want to know who first used the term 'proxy class', good
                      luck in your research.

                      Regards,
                      Buster.

                      Comment

                      • Gianni Mariani

                        #12
                        Re: Which implementation of &quot;set/get&quot; member functions is better?

                        Buster Copley wrote:
                        ....[color=blue]
                        >
                        > It's not a name, but a description. Look up 'proxy' in the dictionary.
                        > If you really want to know who first used the term 'proxy class', good
                        > luck in your research.[/color]

                        By that definition, almost every class is a proxy of some kind.

                        I would call these "property accessor" classes because they control the
                        access to properties.


                        Comment

                        • Kevin Goodsell

                          #13
                          Re: Which implementation of &quot;set/get&quot; member functions is better?Please help.

                          Me wrote:
                          <snip>

                          Please stop top-posting. Re-read section 5 of the FAQ for posting
                          guidelines.



                          -Kevin
                          --
                          My email address is valid, but changes periodically.
                          To contact me please use the address from a recent posting.

                          Comment

                          Working...