Can someone please point me towards some nice resources for understanding and using nested classes? I have some material like Programming Principles and things like this IBM Knowledge Center - Nested Classes
But I'm still having trouble understanding their purpose. Could someone please help me?
6 Answers
Nested classes are cool for hiding implementation details.
List:
class List
{
public:
List(): head(nullptr), tail(nullptr) {}
private:
class Node
{
public:
int data;
Node* next;
Node* prev;
};
private:
Node* head;
Node* tail;
};
Here I don't want to expose Node as other people may decide to use the class and that would hinder me from updating my class as anything exposed is part of the public API and must be maintained forever. By making the class private, I not only hide the implementation I am also saying this is mine and I may change it at any time so you can not use it.
Look at std::list or std::map they all contain hidden classes (or do they?). The point is they may or may not, but because the implementation is private and hidden the builders of the STL were able to update the code without affecting how you used the code, or leaving a lot of old baggage laying around the STL because they need to maintain backwards compatibility with some fool who decided they wanted to use the Node class that was hidden inside list.
Nested classes are just like regular classes, but:
- they have additional access restriction (as all definitions inside a class definition do),
- they don't pollute the given namespace, e.g. global namespace. If you feel that class B is so deeply connected to class A, but the objects of A and B are not necessarily related, then you might want the class B to be only accessible via scoping the A class (it would be referred to as A::Class).
Some examples:
Publicly nesting class to put it in a scope of relevant class
Assume you want to have a class SomeSpecificCollection which would aggregate objects of class Element. You can then either:
declare two classes:
SomeSpecificCollectionandElement- bad, because the name "Element" is general enough in order to cause a possible name clashintroduce a namespace
someSpecificCollectionand declare classessomeSpecificCollection::CollectionandsomeSpecificCollection::Element. No risk of name clash, but can it get any more verbose?declare two global classes
SomeSpecificCollectionandSomeSpecificCollectionElement- which has minor drawbacks, but is probably OK.declare global class
SomeSpecificCollectionand classElementas its nested class. Then:- you don't risk any name clashes as Element is not in the global namespace,
- in implementation of
SomeSpecificCollectionyou refer to justElement, and everywhere else asSomeSpecificCollection::Element- which looks +- the same as 3., but more clear - it gets plain simple that it's "an element of a specific collection", not "a specific element of a collection"
- it is visible that
SomeSpecificCollectionis also a class.
In my opinion, the last variant is definitely the most intuitive and hence best design.
Let me stress - It's not a big difference from making two global classes with more verbose names. It just a tiny little detail, but imho it makes the code more clear.