Thread: Returning pointer/ref to private member

  1. #1

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76

    Returning pointer/ref to private member

    Why is it legal for a class to have a public member function that returns a reference to a private member? Even though this would have to be part of the class definition, giving direct access to a private member variable undeniably violates encapsulation:

    Code:
    class
    {
        private:
            mutable int hidden;
        public:
            int& unHide () const
            {
                return hidden;
            }
    } thing ;
    
    int main()
    {
        // thing.hidden = 1; /* illegal */
    
        int& hidden = thing.unHide () ;
    
        hidden = 1;
    
        return 0;
    }
    Is there any legitimate reason for doing something like this?

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You may want to be able to create a getter, but not a setter, to a class member, for which returning by value is inefficient.
    The point is that private means the outside cannot access it. What the class does with it is up to itself. No sense for C++ to restrict your ability to do things on purpose.
    You can also change your example to return a const reference.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It's legal, and yes, it breaks encapsulation, which is why it's generally discouraged.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    ---
    Join Date
    May 2004
    Posts
    1,379
    That's the beauty about C++. It doesn't force you to do these things. The programmer should know that it is bad OO technique.

  5. #5
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by sand_man View Post
    That's the beauty about C++.
    When you end up working with legacy code and/or code written by others, it turns out to be more of a tragicomedy.

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    519
    Quote Originally Posted by CornedBee View Post
    It's legal, and yes, it breaks encapsulation, which is why it's generally discouraged.

    How would you avoid it (if possible) in the following (stupid) sample:

    Code:
    class HouseDataBase
    {
    public:
       HouseList getHousesWithOpenDoors() const;
       setDoorClosed(int house_id);
    ...
    };
    
    class City
    {
      HouseDataBase mHdb;
    
    public:
      HouseDataBase& getHouseDb();
    ...
    };
    
    int main()
    {
     City city;
    ...
    city.getHouseDb().setDoorClosed(5);
    ...
    }
    Would you propagate the complete interface of the owned class HouseDb through class City? This could be a lot of (redundant) work (imagine more composition Classes like Streets, traffic lights, Cars,...)

    Thank you!

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Wouldn't it be better to create several classes such as House and Car and Light?
    Then you create appropriate said house and add it to the city.
    But you should also be able to fetch a house in a city and perform work on that one.
    This sounds like a design I would use...
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    If I understand correctly, that can be resolved through private inheritance.

    EDIT:
    I don't understand correctly. Are you trying to implement an interface without exposing it to public?
    Last edited by rudyman; 06-30-2008 at 11:54 AM.

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    If I understand correctly, that can be resolved through private inheritance.
    I am not sure what is the problem in the first place. Private inheritance is not a solution here, since to follow pheres' example your City class should also provide a public getHouseDb() member function. If you can remove it in your example, then we can remove it in pheres' example, upon which private inheritance provides no advantage over composition in this case.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I'm not sure I would call a city a HouseDataBase either, so City is "not a" with the other class, in which case inheritance would be wrong.
    But it is true that a City holds houses, so I would say that the current implementation of putting the House database inside the City is more correct.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I'm not sure I would call a city a HouseDataBase either, so City is "not a" with the other class, in which case inheritance would be wrong.
    Private inheritance does not model "is-a", with respect to the public interface.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12

    Join Date
    Apr 2008
    Location
    USA
    Posts
    76
    In an abstract sense, you can use private inheritance to model "has-a", which is why i suggested that in lieu of composition. Although, returning a reference to the privately inherited class defeats the purpose of this, as laserlight pointed out.

    EDIT:
    I think pheres' code is fine the way it is, although one may or may not want to make the City::getHouseDb() return a const reference.
    Last edited by rudyman; 06-30-2008 at 12:47 PM.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I'd return a reference. Possibly const. But only if HouseDataBase is non-copyable.

    Yes, this would mean that I must have an actual HouseDataBase object to back the reference, but I believe that would be a justifiable compromise in this situation.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  14. #14
    Registered User
    Join Date
    Apr 2008
    Posts
    890
    Quote Originally Posted by pheres View Post
    How would you avoid it (if possible) in the following (stupid) sample:
    I'd refactor until it wasn't necessary.

    Code:
    class HouseDataBase {
    public:
        void closeDoor(int houseId);
    };
    
    class City {
        HouseDataBase mHdb;
    public:
        void closeHouseDoor(int houseId) { mHdb.closeDoor(houseId); }
    };
    
    int main()
    {
        City city;
    
        city.closeHouseDoor(5);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you check what is wrong with this code
    By Ron in forum C++ Programming
    Replies: 4
    Last Post: 08-01-2008, 10:59 PM
  2. Replies: 2
    Last Post: 02-14-2008, 02:59 PM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Returning the address of a member structure
    By cunnus88 in forum C++ Programming
    Replies: 4
    Last Post: 05-03-2006, 12:51 AM
  5. Post programs
    By GaPe in forum C# Programming
    Replies: 8
    Last Post: 05-12-2002, 11:07 AM