Question on Myers #30

Discussion in 'C++' started by Master of C++, Feb 26, 2005.

  1. Hi,

    In Effective C++, #30, Myers says:

    "Avoid member functions that return pointers or references to members
    less accessible than themselves"

    But, operator[] does exactly the opposite. Is overloading operator[]
    considered "evil" in C++ circles ? I write a lot of numerical
    programming code, and such operators make life easier for me.

    Thanks,
    Vijay.
     
    Master of C++, Feb 26, 2005
    #1
    1. Advertising

  2. * Master of C++:
    >
    > In Effective C++, #30, Myers says:
    >
    > "Avoid member functions that return pointers or references to members
    > less accessible than themselves"
    >
    > But, operator[] does exactly the opposite. Is overloading operator[]
    > considered "evil" in C++ circles ? I write a lot of numerical
    > programming code, and such operators make life easier for me.


    "Effective C++" et.al. is just a compendium of rules-of-thumbs for
    newbies. Very good for that, not very good when you understand the
    issues and can apply intelligence rather then rote rules. The advice
    cited above is, however, good for nothing... ;-)

    A member function that returns a pointer or reference to a member
    as accessible or more accessible than itself, is usually meaningless.

    Perhaps the above is just a typo.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 26, 2005
    #2
    1. Advertising

  3. Alf P. Steinbach wrote:

    > A member function that returns a pointer or reference to a member
    > as accessible or more accessible than itself, is usually meaningless.
    >
    > Perhaps the above is just a typo.



    I am not for the "usually" part. I am using many methods returning const
    references, references or pointers to data members.



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 26, 2005
    #3
  4. Ioannis Vranos wrote:

    > I am not


    sure

    > for the "usually" part. I am using many


    API

    > methods returning const
    > references, references or pointers to data members.




    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 26, 2005
    #4
  5. * Ioannis Vranos:
    > Ioannis Vranos wrote:
    >
    > > I am not

    >
    > sure
    >
    > > for the "usually" part. I am using many

    >
    > API
    >
    > > methods returning const
    > > references, references or pointers to data members.


    Well, are you for example calling a public member function getHeight()
    to obtain a reference to a public member mHeight, height_, myHeight?

    Or a protected member function to obtain a reference to a protected
    member, or a private one to obtain a reference to a private one?

    That's what I think is usually very meaningless; the protection level of the
    data member is then IMO not strict enough (which except for the "usually"
    excludes private member function returning reference to private member,
    but there might be a case for a virtual such).

    I may be wrong though.

    Perhaps if someone could quote or describe Myers' rationale?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 26, 2005
    #5
  6. Master of C++

    White Wolf Guest

    Alf P. Steinbach wrote:
    [SNIP]
    > Perhaps if someone could quote or describe Myers' rationale?


    It's Meyers. Scott Meyers. Shaken, not stirred. ;-)

    --
    WW aka Attila
    :::
    There are no passengers on spaceship Earth - we are all the crew.
     
    White Wolf, Feb 26, 2005
    #6
  7. Alf P. Steinbach wrote:

    > Well, are you for example calling a public member function getHeight()
    > to obtain a reference to a public member mHeight, height_, myHeight?




    Actually yes, this one in the form of (system-dependent) properties
    implemented as getheight() and setheight() methods, which are implicitly
    called.


    But let's stick in another portable example:

    vector's operator[] doesn't return a reference? Or begin() an iterator?


    Isn't the following style common?


    class SomeClass
    {
    string name;

    // ...

    public:

    const string &getname() const { return name; }

    void setname(const string &newname) { name= newname; }

    // ...
    };



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 26, 2005
    #7
  8. * Ioannis Vranos:
    > Alf P. Steinbach wrote:
    >
    > > Well, are you for example calling a public member function getHeight()
    > > to obtain a reference to a public member mHeight, height_, myHeight?

    >
    >
    >
    > Actually yes, this one in the form of (system-dependent) properties
    > implemented as getheight() and setheight() methods, which are implicitly
    > called.


    Hm, not sure what you mean.


    > But let's stick in another portable example:
    >
    > vector's operator[] doesn't return a reference? Or begin() an iterator?


    They do, and the members they return references to are less accessible
    (contrary to Meyers' advice).


    > Isn't the following style common?
    >
    >
    > class SomeClass
    > {
    > string name;
    >
    > // ...
    >
    > public:
    >
    > const string &getname() const { return name; }
    >
    > void setname(const string &newname) { name= newname; }
    >
    > // ...
    > };


    Yep, and again, contrary to Meyers' advice. Although I'd return that
    string by value and let the compiler to the optimization.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 26, 2005
    #8
  9. Alf P. Steinbach wrote:

    >>Isn't the following style common?
    >>
    >>
    >>class SomeClass
    >>{
    >> string name;
    >>
    >> // ...
    >>
    >> public:
    >>
    >> const string &getname() const { return name; }
    >>
    >> void setname(const string &newname) { name= newname; }
    >>
    >> // ...
    >>};

    >
    >
    > Yep, and again, contrary to Meyers' advice. Although I'd return that
    > string by value and let the compiler to the optimization.



    If you return the string by value most chances are that you will have a
    redundant call to the copy constructor of the string for the temporary,
    with a full copy of all its members.


    In strings and other containers with large size, this is a major
    drawback. That's why we have references and pointers.


    I am not sure what Meyers means with that quote, but only he can explain
    what he means exactly. The bottom line is, one should use const
    references and const pointers instead of redundant temporaries, as much
    as he can.


    Perhaps Meyers means non-const references and pointers specifically, and
    not the const ones. That is, I could agree with this:


    "Avoid member functions that return non-const pointers or references to
    members less accessible than themselves".



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 26, 2005
    #9
  10. Of course, I don't follow EC++ as if it were a rule-book. But a lot of
    well-respected authors (Herb Sutter, Steve McConnell etc.,) cite Myers
    heavily, and I have respect for what he says in his book. Thats what
    makes this advice a little confusing.

    Its not a typo. I verified it before posting.

    -Vijay.
     
    Master of C++, Feb 26, 2005
    #10
  11. Master of C++

    Guest

    if you are overloading operator[] for example for Array class, it is
    not contrary to Myers, because Myers said that for general design, but
    I think CONTAINER classes are exception to this rule.
     
    , Feb 26, 2005
    #11
  12. Master of C++

    Phil Staite Guest

    Master of C++ wrote:
    > Hi,
    >
    > In Effective C++, #30, Myers says:
    >
    > "Avoid member functions that return pointers or references to members
    > less accessible than themselves"


    Seems straightforward to me. IMHO if you give out a pointer or
    reference to any data member you're violating encapsulation. (but yes,
    sometimes it has to be done) As Mr. Meyers points out, giving out
    pointers or refs to data members with more restricted access (eg. a
    public member function returning a pointer to a private member) is even
    worse. Heck, you might as well just make the member public and call it
    a struct... ;-)

    Additionally, just the fact that you're returning pointers/refs to data
    members is suspect. Generally that means your data is in one place or
    class, and the code that operates on it is in another. Not good for
    encapsulation. And yes, I know there are many many exceptions to this
    idea and instances where you just "have to" expose data/members in some
    ways. I'm just saying if you're doing that, make sure you're doing it
    for a good/valid reason.
     
    Phil Staite, Feb 26, 2005
    #12
  13. Master of C++

    Rances Guest

    "Phil Staite" <> wrote in message
    news:...
    > Master of C++ wrote:
    >> Hi,
    >>
    >> In Effective C++, #30, Myers says:
    >>
    >> "Avoid member functions that return pointers or references to members
    >> less accessible than themselves"

    >
    > Seems straightforward to me. IMHO if you give out a pointer or reference
    > to any data member you're violating encapsulation. (but yes, sometimes it
    > has to be done)


    PUblic functions returning const references to large private data members
    such as vectors is a pretty good design pattern IMO. You can use the
    reference in a const manner very efficiently, or use an inneficient copy in
    a non-const manner.
     
    Rances, Feb 26, 2005
    #13
  14. Rances wrote:

    > PUblic functions returning const references to large private data members
    > such as vectors is a pretty good design pattern IMO. You can use the
    > reference in a const manner very efficiently, or use an inneficient copy in
    > a non-const manner.



    Also, a return of a const reference or const pointer to something does
    not necessarily expose the internal data of a class, although in most
    times it is internal data of the class, however it may be not, and thus
    it is not against data hiding.


    Bottom line is, returning a redundant string temporary which is a copy
    of an internal string member does not provide any more data hiding than
    a const reference or pointer to the same string member.



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 26, 2005
    #14
  15. Master of C++

    White Wolf Guest

    Master of C++ wrote:
    > Of course, I don't follow EC++ as if it were a rule-book. But a lot of
    > well-respected authors (Herb Sutter, Steve McConnell etc.,) cite Myers
    > heavily, and I have respect for what he says in his book. Thats what
    > makes this advice a little confusing.


    No, they don't.

    > Its not a typo. I verified it before posting.


    It is a typo. The book is written by Scott Meyers.

    --
    WW aka Attila
    :::
    A red sign on the door of a physics professor: 'If this sign is blue,
    you're going too fast.'
     
    White Wolf, Feb 27, 2005
    #15
  16. * Ioannis Vranos:
    > Rances wrote:
    >
    > > PUblic functions returning const references to large private data members
    > > such as vectors is a pretty good design pattern IMO. You can use the
    > > reference in a const manner very efficiently, or use an inneficient copy in
    > > a non-const manner.

    >
    >
    > Also, a return of a const reference or const pointer to something does
    > not necessarily expose the internal data of a class, although in most
    > times it is internal data of the class, however it may be not, and thus
    > it is not against data hiding.


    Agreed.


    > Bottom line is, returning a redundant string temporary which is a copy
    > of an internal string member does not provide any more data hiding than
    > a const reference or pointer to the same string member.


    Well, the reference actually _is_ an exposure. A common case where this may
    bite you (at least it tried to gnaw some meat off my leg, I just
    kicked it very hard and never seen it since) is where you want to change the
    internal implementation so you no longer have a member. It's probably a
    purely philosophical question where the blame really is, then: the reference
    result, versioning, ill-behaved client code, what, but in practice problems
    can be avoided simply by avoiding the reference result in the first place. As
    I see it it's definitely a case of Knuth's evil premature optimization.
    Keeping one's set of options open is, after all, the favorite strategy of good
    programmers, who thereby are lazy by definition, I find that interesting....

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 27, 2005
    #16
  17. Alf P. Steinbach wrote:

    > Well, the reference actually _is_ an exposure. A common case where this may
    > bite you (at least it tried to gnaw some meat off my leg, I just
    > kicked it very hard and never seen it since) is where you want to change the
    > internal implementation so you no longer have a member. It's probably a
    > purely philosophical question where the blame really is, then: the reference
    > result, versioning, ill-behaved client code, what, but in practice problems
    > can be avoided simply by avoiding the reference result in the first place. As
    > I see it it's definitely a case of Knuth's evil premature optimization.
    > Keeping one's set of options open is, after all, the favorite strategy of good
    > programmers, who thereby are lazy by definition, I find that interesting....



    If you want to keep the old programming interface of your class, you can
    easily change const string & to const string.


    If you were returning a non-const reference(!) to your internal data
    member, then you shouldn't do it.


    What Meyers is saying is absolutely right for non-const references, and
    my guess is that it is what he means.



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 27, 2005
    #17
  18. * Ioannis Vranos:
    >
    > If you want to keep the old programming interface of your class, you can
    > easily change const string & to const string.


    Not without potentially breaking client code.


    > If you were returning a non-const reference(!) to your internal data
    > member, then you shouldn't do it.


    Right.


    > What Meyers is saying is absolutely right for non-const references, and
    > my guess is that it is what he means.


    That doesn't seem to follow.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 27, 2005
    #18
  19. Alf P. Steinbach wrote:

    >>If you want to keep the old programming interface of your class, you can
    >>easily change const string & to const string.

    >
    >
    > Not without potentially breaking client code.



    May you provide an example?



    --
    Ioannis Vranos

    http://www23.brinkster.com/noicys
     
    Ioannis Vranos, Feb 27, 2005
    #19
  20. * Ioannis Vranos:
    > Alf P. Steinbach wrote:
    >
    > >>If you want to keep the old programming interface of your class, you can
    > >>easily change const string & to const string.

    > >
    > >
    > > Not without potentially breaking client code.

    >
    >
    > May you provide an example?



    void client( bool thisOrThat )
    {
    std::string const gwb = "Bah!";
    std::string const* ps = thisOrThat? &gwb : &iv.getstring();

    std::cout << *ps << std::endl;
    }

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Feb 27, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. sean
    Replies:
    1
    Views:
    629
    Cowboy \(Gregory A. Beamer\)
    Oct 20, 2003
  2. =?Utf-8?B?UnlhbiBTbWl0aA==?=

    Quick Question - Newby Question

    =?Utf-8?B?UnlhbiBTbWl0aA==?=, Feb 14, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    700
    Iain Norman
    Feb 16, 2005
  3. =?Utf-8?B?YW5kcmV3MDA3?=

    question row filter (more of sql query question)

    =?Utf-8?B?YW5kcmV3MDA3?=, Oct 5, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    981
    Scott Allen
    Oct 6, 2005
  4. Philip Meyer
    Replies:
    0
    Views:
    451
    Philip Meyer
    Nov 30, 2003
  5. ma740988
    Replies:
    7
    Views:
    469
    Alf P. Steinbach
    Jun 22, 2009
Loading...

Share This Page