10.5. Aggregation: Pointer Member Variables

Time: 00:01:49 | Download: Large, Large (CC), Small | Streaming (CC) | Slides (PDF)

In our previous discussion of classes and objects, we limited ourselves to non-pointer member variables. Adding pointer members increases the power and flexibility of object-oriented programs and allows programmers to implement more UML class relationships. Nevertheless, allowing pointer members also increases the complexity and effort of programming with classes and objects.

The textbook uses two non-standard, working definitions to make it easier for us to talk about pointer and non-pointer class members:
A simple class or object is:
A class or object without any pointer member variables.
A complex class or object is:
A class or object with one or more pointer member variables.
A UML class diagram showing three private member variables. The first is a string pointer called name, the second is an integer called weight, and the last is a double called height.
class Person
{
    private:
	string*	name;
	int	weight;
	double	height;
};
An abstract representation of what an instance of the Person class looks like in memory. A large rectangle represents the Person object, with three small rectangles inside. The smaller rectangles represent the three member variables: name, weight, and height. An arrow points from the name rectangle to a fourth rectangle, drawn outside of the <kbd>Person</kbd> rectangle, representing an instance of the string class - the pointer variable points to the string object.
(a)(b)(c)
A class with a pointer member variable.
  1. A UML class diagram illustrating the member variables in the Person class. UML diagrams are language agnostic; nevertheless, we include the asterisk to emphasize that the name member is a pointer.
  2. The C++ specification of class Person. The member variable name points to an instance of the string class.
  3. Making a member variable a pointer leaves the data physically separate from the object. In this example, the person's name is in a string object existing outside of the Person.

Syntactically, adding a pointer member variable to a class is seemingly trivial - adding an asterisk to one or more of the variable names. But conceptually, the change has significant consequences. When we change a member variable from a non-pointer to a pointer, we also change the relationship from composition to aggregation. Changing the relationship means changing a strong, tight binding to a loose, weak one. Aggregated objects may have different lifetimes, the whole can share its parts with other objects in the program, and the whole can discard or replace its parts whenever convenient. The increase in complexity requires us to explore five distinct concepts related to pointer member variables:

  1. Initializing pointer members with constructors and setters
  2. Using pointer members
  3. Destroying (i.e., deleting) objects with destructors
  4. Testing for a nullptr before using a pointer
  5. Overriding the copy constructor

We explore these concepts in the following sections.