Naming convention for accessor methods (get/set)

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

    #16
    Re: Naming convention for accessor methods (get/set)

    I believe Stroustrup favours the style of accessor where a single
    overloaded function name is used for both getting and setting.
    At least, ISTR seeing such a thing in the C++ book, and didn't see
    any get_x() or set_x() methods.

    --
    Ed Avis <ed@membled.com >


    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]

    Comment

    • Ed Avis

      #17
      Re: Naming convention for accessor methods (get/set)

      "Marcin Vorbrodt" <mvorbro@eos.nc su.edu> writes:
      [color=blue]
      >class A {
      > public:
      > int& EVIL() { return _evil; }
      > const int& EVIL() const { return _evil; }
      >};
      >
      >This really is a horrible design... because you are exposing the underlying
      >implementati on of your class.[/color]

      It's not necessarily evil - for some concrete types it may be simplest
      to expose the implementation. If a complex number has 'real' and
      'imag', and you don't plan to change to polar coordinates later, you
      might as well expose those rather than clutter the interface with
      accessors. Especially so if you are writing this class for your own
      use and can simply change all the callers in the unlikely event of the
      implementation changing.

      However if you are writing a class for 'complex number with magnitude
      less than 1', then you wouldn't make the members public because it
      would let a caller too easily break the class invariant.
      [color=blue]
      >If you need to be able to create setters and getters, why not just
      >make the variable public.[/color]

      Indeed. The above code, however, may be preferred in shops where
      coding standards mandate using accessors for all members and never
      making them public. It's a way to simulate public visibility, in
      cases where that would be the best design, while staying within the
      letter of the religious law. (Of course, in such cases the accessors
      would probably be called getEvil() or getMyEvil() or
      pIGetMyEvilAsRe ference().)

      --
      Ed Avis <ed@membled.com >

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • James Kanze

        #18
        Re: Naming convention for accessor methods (get/set)

        apm35@student.o pen.ac.uk (apm) writes:

        |> usenet@sta.sams ung.com (Generic Usenet Account) wrote in message news:<90e5135.0 309181203.cb6be e0@posting.goog le.com>...

        |> > A lot has been said in this newsgroup regarding the "evil" set/get
        |> > accessor methods. Arthur Riel, (of Vanguard Training), in his
        |> > class, "Heuristis for O-O Analysis & Design", says that there is
        |> > almost never an excuse for accessor methods. Personally, I do not
        |> > go that far. I do feel that they serve a useful purpose (albeit in
        |> > a limited manner). Personally I prefer dropp

        |> So do I. Here's why:

        |> The Uniform Access Principle espoused by Betrand Meyer states that
        |> all services offerd by a module should be available through a
        |> uniform notation which does not betray whether they are implemented
        |> through storage or through computation. Get get/set convention
        |> violates this.

        So do any of the alternatives in C++.

        Or rather, none of them do, if used consistently. How does get and set
        betray the underlying implementation?

        --
        James Kanze mailto:kanze@ga bi-soft.fr
        Conseils en informatique orientée objet/
        Beratung in objektorientier ter Datenverarbeitu ng
        11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93

        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
        [ comp.lang.c++.m oderated. First time posters: Do this! ]

        Comment

        • Dave Harris

          #19
          Re: Naming convention for accessor methods (get/set)

          mvorbro@eos.ncs u.edu (Marcin Vorbrodt) wrote (abridged):[color=blue]
          > class A {
          > public:
          > int& EVIL() { return _evil; }
          > const int& EVIL() const { return _evil; }
          > };
          >
          > This really is a horrible design... [...] If you need to be able
          > to create setters and getters, why not just make the variable
          > public.[/color]

          There are degrees of encapsulation. Your interface at least allows
          some indirection. For example:

          int &EVIL() {
          if (_pImpl == NULL)
          _pImpl = new Impl;
          return _pImpl->EVIL();
          }

          There is quite a lot of flexibility available. Eg if A has more than
          one variable, we can use more than one Impl class and allocate them
          at different times.

          Reference-returning functions restrict the implementation less than
          exposing an actual instance variable. Personally I avoid them (even
          for things like vector::operato r[]), but they are not evil.

          -- Dave Harris, Nottingham, UK

          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
          [ comp.lang.c++.m oderated. First time posters: Do this! ]

          Comment

          • Torsten Robitzki

            #20
            Re: Naming convention for accessor methods (get/set)

            Generic Usenet Account wrote:
            [color=blue]
            > A lot has been said in this newsgroup regarding the "evil" set/get
            > accessor methods. Arthur Riel, (of Vanguard Training), in his class,
            > "Heuristis for O-O Analysis & Design", says that there is almost never
            > an excuse for accessor methods. Personally, I do not go that far. I
            > do feel that they serve a useful purpose (albeit in a limited manner).
            > Personally I prefer dropping the "set" and "get" prefixes from the
            > method names altogether. For example:
            >
            > class A
            > {
            > public:
            > ...
            > int xyz() { return _xyz; } // instead of get_xyz()
            > void xyz(const int val) { _xyz = val; } // instead of get_xyz()
            > ...
            >
            > protected:
            > ...
            > int _xyz;
            > ...
            > };
            >
            >
            > This naming convention is also consistent with the IDL/C++ language
            > binding, and I wanted to seek your opinion regarding this.[/color]

            I'm unsure if you are looking for opinions of if accessor functions are
            a design mistake or how to name them in the rare cases where they are
            useful.

            For the latter I would call them getX() and setX() (or get_x...) just
            for the case I have to address one of the functions as an parameter to
            an ScopeGuard to rollback a prior set value back to its original value.

            But if you are looking for some excuse to use accessors (especial
            setters) I would tend to say that it's a design flaw in most cases. I
            experienced two situations in my career by now, where setters where
            useful. The first was a class that cached configuration data from a data
            base by it's getters but also had setters to change the configuration.
            But the setters didn't only updated the configuration into the DB but
            informed other processes about the configuration changes, so the same
            class linked into an other process read the configuration from the DB.
            The second case where I used setters where I had to create Object as
            copy from other object and to make little changes on them.

            regards Torsten


            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
            [ comp.lang.c++.m oderated. First time posters: Do this! ]

            Comment

            • Glen Low

              #21
              Re: Naming convention for accessor methods (get/set)

              > This naming convention is also consistent with the IDL/C++ language[color=blue]
              > binding, and I wanted to seek your opinion regarding this.[/color]

              C++ iostreams uses the int xyz(); void xyz(int) convention as well.

              What is so evil about accessors/mutators, if they are not "just"
              returning the underlying data member? (They could be calculating it,
              caching it or passing it on to another object for example.)

              Here's a suggestion to make the accessor/mutator pair into a first
              class object, akin (but better in the long run) to VB/C# property,
              your thots please.

              We define a property class (with appropriate templating) to declare:

              property& operator= (T);
              operator T() const;

              The signature is the same or similar to the proxy objects that often
              crop up in delayed dereferencing scenarios.

              The class contains a reference to the underlying object, and two PMFs
              (either as template non-type params or constructor params) to the
              [private] accessor/mutators in the object.

              The object can either expose the property as a public data member (I'm
              going to get into trouble for this one...), or through a member
              function.

              The former allows you to do this:
              a.xyz = 12; std::cout << a.xyz;

              The latter is slightly clunkier:
              a.xyz() = 12; std::cout << a.xyz();

              If the latter, a compiler would probably just optimize away the
              property temporary anyway. (The latter also allows indexing
              scenarios.)

              What else does this buy you? The property can now be used as an
              object, a substitute for a reference e.g.

              template <typename U> void mul (U& z, const U& x, const U& y) { z = x
              * y; }

              Now mul could only take U = int before. But it can now take a property
              and it will do the right thing. A bit similar to how an STL iterator
              is an extension of the pointer, the property is like an extension to
              reference. mul would not work with the pair of accessor/mutator
              unwrapped.

              Any comments, caveats, thoughts on this?

              Cheers,
              Glen Low, Pixelglow Software


              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • Shay

                #22
                Properties (was: Naming convention for accessors...)

                Glen Low wrote:
                [snip][color=blue]
                > Here's a suggestion to make the accessor/mutator pair into a first
                > class object, akin (but better in the long run) to VB/C# property,
                > your thots please.
                >
                > We define a property class (with appropriate templating) to
                > declare:
                >
                > property& operator= (T);
                > operator T() const;
                >
                > The signature is the same or similar to the proxy objects that
                > often crop up in delayed dereferencing scenarios.
                >
                > The class contains a reference to the underlying object, and two
                > PMFs (either as template non-type params or constructor params) to
                > the [private] accessor/mutators in the object.
                >
                > The object can either expose the property as a public data member
                > (I'm going to get into trouble for this one...), or through a
                > member function.[/color]

                Exposing a member doesn't have to constrain the enclosing class at all:

                class X {
                X( X const& );
                X& operator = ( X const& );
                void operator & () const;
                // anything else I left out :)
                };

                class Foo {
                public:
                X x; // what does this expose other than Foo having an X named x?
                };
                [color=blue]
                > What else does this buy you? The property can now be used as an
                > object, a substitute for a reference e.g.
                >
                > template <typename U> void mul (U& z, const U& x, const U& y) { z =
                > x * y; }
                >
                > Now mul could only take U = int before. But it can now take a
                > property and it will do the right thing. A bit similar to how an
                > STL iterator is an extension of the pointer, the property is like
                > an extension to reference. mul would not work with the pair of
                > accessor/mutator unwrapped.[/color]

                With properties added to the mix, a class could be seen as a collection of
                members, each with a particular interface. A data member is an entity
                which stores a value and allows access to it. A member function is an
                entity which has an operator () and implements it via its definition, or
                via the virtual dispatch mechanism. A value property is an entity which
                acts like a value but implements get and set via function call rather than
                by-value storage within itself.

                This value property allows accessible abstract state to be expressed more
                directly, and manipulated using the already-existing mechanisms for values
                (as your example shows). At the core of this is the recognition that a
                class is a collection of interface elements, and we can start thinking of
                expansion of the usual set.

                I described this value property in a way that I hope hints at further
                possibilities. One is backwards-compatibility with overloaded accessor
                functions that it might have replaced: a value property can define
                operator () () as a getter and operator () ( value_type ) as a setter.
                There could be a "cached value property" which keeps a copy of its value
                and gives this out when it is read, and when it is written, only invokes
                the "set new value" callback if the new value is different than the old
                one.

                It's also possible to go beyond values. How about a readable boolean flag
                with an optional callback that is invoked when it changes value? This
                property would keep track of the current value, allow reading of this, and
                allow registration of a callback function. The enclosing class would keep
                this flag up-to-date, but wouldn't have to bother with the callback. The
                property would have public functions and "parent-only" functions that were
                only accessible to the enclosing class (here there would be a parent-only
                function to change the flag's value).

                How about a counted entry/exit with parent notification on first
                entry/last exit? Here the property stores the entry count, has member
                functions entry() and exit(), and two callbacks to the parent,
                first_entry() and last_exit().

                I've done a little experimentation with data providers and consumers. I
                made a supplier and consumer property. It uses an intrusive circular
                doubly-linked "ring" and traversed it when the provider had a new value. A
                class might supply many different values, so each one could be a separate
                property.

                A property could be thought of as being just like a base class, except
                that its interface isn't injected into the parent class but rather appears
                as part of the interface of a member of the parent class. The parent class
                can override "virtual" functions in the property and gets special access
                like a derived class can.

                Properties have two clients: general clients and the parent class. I think
                of the electronics field where there are user-interface devices which have
                internals and an interface to the device. Think of a simple toggle switch:
                It has a button that the user can press (the public interface), two wires
                which are either electrically open or closed (the parent-only interface),
                and a mechanism to keep the current open/closed state latched and toggle
                it when the button is pressed. Without property elements, the engineer's
                equivalent would be mounting the toggle switch inside the device and
                running a long mechanical bar from the button to the case (i.e. connect
                the button's interface to the public via a member function).

                A fine point I encountered in various implementations : with the
                introduction of property values, the value type might differ from the
                object type. An int stores an int, but a value_property< int> doesn't store
                a value_property< int>. I solved this with a simple value_type<> type
                mapping, where value_type<int> ::type and value_type<valu e_property<int>[color=blue]
                >::type both yielded int. This allowed simple scoped value restoration[/color]
                which worked for any value type.

                I've implemented several very crude libraries for experimentation with
                properties over the years. I implemented quite a few properties in various
                classes (file streams, audio output, GUI controls) but never really found
                much use for them. Because I had the possibility of implementing ideas of
                new properties, I was open to places to add them, but very few ideas ever
                came. I'd be interested in brainstorming places where they might be
                useful, then looking critically or even trying it out. I think that the
                ability to do hands-on experiments is very important for growing and even
                the abandoning of ideas. I have a feeling that the property idea might not
                be viable, but I want to see it demonstrated. I'm not content with
                reasoning it away, because most reasoning I've encountered seemed aimed at
                avoiding the possibility of something new rather than making insights as
                to the flaws.

                --
                Shay

                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                Comment

                • Jerry Coffin

                  #23
                  Re: Naming convention for accessor methods (get/set)

                  In article <9215d7ac.03093 01848.7ad3a2df@ posting.google. com>,
                  glenlow@pixelgl ow.com says...

                  [ ... ]
                  [color=blue]
                  > We define a property class (with appropriate templating) to declare:
                  >
                  > property& operator= (T);
                  > operator T() const;
                  >
                  > The signature is the same or similar to the proxy objects that often
                  > crop up in delayed dereferencing scenarios.[/color]

                  This was suggested in a rather lengthy thread years ago in comp.std.c++.
                  Feel free to read through the thread starting at:



                  for various views on the subject.
                  [color=blue]
                  > The object can either expose the property as a public data member (I'm
                  > going to get into trouble for this one...), or through a member
                  > function.[/color]

                  IMO, in a situation like this, the member function provides no real
                  capabilities to compensate for the obfuscation.

                  --
                  Later,
                  Jerry.

                  The universe is a figment of its own imagination.

                  [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                  [ comp.lang.c++.m oderated. First time posters: Do this! ]

                  Comment

                  Working...