1

Is this design bad?

Does it break encapsulation? The structure class B is a component of class A. Therefore, class A needs access to class B's members. Let a house be class A. Let a housekeeper be a component of class A. Let a room be class B. A room, and therefore class B, is a component of class A.

A housekeeper needs access to room's members to switch bedroom_dirty = true to bedroom_dirty = false, for example. A housekeeper does not belong in a room (i.e. class B); that would be a roomkeeper, and we are not talking about that.

Is this design bad?

class A
{
  class B
  { 
    friend class A{}; // A has access to all of B's members
  };
};
7
  • 2
    Class B is encapsulated in class A already anyway. As with most things in computing, it really depends on what you want to accomplish. Commented Jun 26, 2016 at 20:54
  • @RobertHarvey What you're telling me is that the structure class B has its data members hidden from class A. Not quite, if A is a friend class of B. A is able to access B's members. This breaks encapsulation, and therefore breaks an object-oriented principle. Therefore, the design is bad. Commented Jun 26, 2016 at 21:04
  • I never said that. If you've already made up your mind that the design is bad, then why are you asking us? Commented Jun 26, 2016 at 22:01
  • @RobertHarvey, you said class B is encapsulated inside class A. The definition of encapsulation is to hide data. I provided an argument that this design is bad, and want to see if you can reason with me that this is a good design. Clearly, our argument is not an argument, and is not going anywhere. Commented Jun 26, 2016 at 22:03
  • It might be a valid argument if you knew what you were talking about. Commented Jun 26, 2016 at 22:03

1 Answer 1

3

Why nested classes ?

Bjarne Stroustrup explains in "The design and evolution of C++", the origin and rationale behind nested classes:

  • original C++ in 1984 had a single name space (page 5 and 102).
  • the use of nested classes was a compromise between the the concept of a class as a scope and the need of compatibility with C (page 102)
  • it was further desired to promote the principle of locality, i.e. self contained reusable pieces of code. Nested classes appear to contribute to this objective (page 118)
  • Namespaces as we know them today were only added to the language in 1993. This finally allowed to express modularity above the class and the file.

Relation between inner and outer class

So the nesting of classes allows to manage scope and hide implementation details.

If the nested class is public, an alternative valid approach would be to put the outer and the inner class in an intermediary namespace.

Furthermore, Bjarne Stroustrup recommends for generic classes that: "The designers of a generic class should carefully consider the relationship between its type parameters and its nested classes; if an inner class does not depend on all the type parameters, it should be moved outside and be replaced with an alias that minimizes the dependencies.".

So if you would give to the inner class access to the internals of the outer class, you would break encapsulation principles if you would choose to refactor your solution to a non nested alternative.

Conclusion

Considering all this, it appears clear that the inner class and the outer class should be considered as plain classes and obey to the usual principle of encapsulation.

The inner class should hence if possible not be a friend of the outer class. Instead, call an appropriate member function to set the flag:

class A
{
    bool bedromm_dirty; 
public: 
    void set_dirty(bool dirt); 
    inline bool get_dirty() const { return dirty; }

    class B  // would work also if not nested
    {        // no change needed if dirt would be managed with bit flags
    public:  
        void clean_room(class A&) { set_dirty(false); }
    };
};
1
  • bedroom_dirty belongs in class B. Commented Jun 27, 2016 at 11:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.