Friends and Nested Classes

Friend classes

Earlier this semeseter we discussed how and why to make a function a friend of your class. It's also possible to declare another class to be a friend of your class. Doing so is just a short-hand way of saying "All member functions of my friend class are my friend".

A good reason for friends

Recall from earlier this semester that a class may grant special access to its private data members by declaring a function (or another class) as its friend.

We mentioned the use of friend functions earlier this semester, but then didn't use them much in the projects. The reason is that we usually had a better alternative. But sometimes there's a good reason for a class or function to be a friend of a class.

Often, multiple classes are necessary to implement a single abstraction. For example, a List might be implemented as a linked list using a List class and a Node class. Since these two classes work very closely together (we say they are "tightly coupled"), it would make sense for some kind of friendship to exist between them.

Here are a List and Node class that might implement a List. The user of a List should have no knowledge that the List is in fact a linked list, so the user should have no access to the Node class. The List class, on the other hand, has intimate knowledge of the Node class. Both of these relationships are accomplished by making all data and methods of the Node class private and making the List a friend of the Node.

template < class T > class List<T>; // a "forward declaration" template< class T > class Node { private: Node( ); Node* m_next; int m_data; friend class List<T>; }; template< class T > class List { public: List( ); // other public stuff private: Node<T> *m_header; }; As is the case here, when classes are in a friendly situation, there is "circular" relationship -- both classes reference the other. This situation is handled by means of the "forward declaration".

Nested Classes

In some situations, one class is so tightly coupled to another that one class is hidden. One class is defined inside another class and is called a "nested" or "embedded" class. We could have chosen this approach for the List and Node above. template< class T > class List { public: List( ); // other public stuff private: template< class U > class Node { private: Node( ); Node< U >* m_next; int m_data; }; Node< T > *m_header; }; A nested class (Node) can be private which means it cannot be used outside of the outer class (List). A nested class (Node) could also be public which means it can be used outside of the outer class (List), however its name must be specified as List<T>::Node<T>.

Last Modified: Monday, 28-Aug-2006 10:16:07 EDT