Suppose we have two classes, Foo and Bar and we would like every Foo to have a Bar. We can represent that with the following class definitions:
class Bar {}; // Not interested in what Bar consists of right now. class Foo { public: private: Bar myBar; // Every Foo has a Bar. int someOtherData; };
This is referred to as composition. It is also called containment. What is implied by this arrangement?
So, when might we want a different design?
Any of these would require that we use a different arrangement. For example, if Bar is actually the same class a Foo, then we are proposing the following class:
class Foo { public: private: Foo myFoo; // Every Foo has a Foo. int someOtherData; };
But this says that inside a Foo is another Foo. Not only that but it has someOtherData, which is an int. How can I fit a Foo inside another Foo. Every Foo is the same size, but if one was inside another wouldn't the second one have to be bigger than the one that's inside of it??? Definitely a problem.
How could we come up with such a problem? Consider a Person class, in which we want to store the possibilty that a Person has a spouse (i.e., a husband or a wife). The class might look like:
class Person { private: string name; Person spouse; };
It should be clear that a Person can't have space to have another Person inside of him/her. Also, most people are not born with a spouse. And sadly, sometimes we may have to allow for losing a spouse or even acquiring another. (We are not trying to handle multiple simultaneous spouses.)
How can we handle these issues in C++? We can make our member variable into a pointer. In the case of the Person with a spouse, the class could be written as:
class Person { private: string name; Person* spouse; };
The only difference is that now spouse is a pointer to a Person, instead of
a Person. Since a pointer variable just holds an address, there is not difficulty
in storing a pointer to a Person inside of a Person.
How does this approach help us with the other problems mentioned earlier? What
value could we store in spouse if a Person is not currently married? In other
words, what value can we use to say that the variable spouse is not actually
pointing to another Person? NULL. The value NULL for a pointer variable always
means the variable is not pointing at anything. That makes pointers ideal when
you might need a variable that sometimes refers to an object and other
times doesn't refer to anything at all.
Maintained by John Sterling (jsterling@poly.edu). Last updated January 23, 2011