Aggregation / Composition: Objects as Class Members
- Aggregation (or composition) is a relationship between
objects
- implemented by embedding an object of one class type (or a pointer or
reference) inside as member data of another class type
- This is the idea of objects embedded inside other objects
(components making up the "aggregate")
- Some developers use the term composition to refer to a stronger
form of aggregation, where the embedded objects (the components)
would typically not exist independent of the container object
- Often known as the "has-a" relationship:
- We might place an Engine object inside a Car object
as member data, because a "car has an engine"
- We could place 52 Card objects as member data of class
Deck, because a "deck has 52 cards"
- Promotes the idea of "tool building".
- A class is a new type. Objects of this type can now be used as
components inside other classes
Timer class example:
This example contains two classes -- Display and Timer. You can access
the code here.
The files are:
-
timer.h -- header file, which consists of declarations for the
Display class and the Timer class
-
timer.cpp -- implementation file, which consists of member
function definitions for the Display and Timer classes
-
main.cpp -- main program file, which is a driver program
illustrating some tests on the Timer class features. The main
program also contains examples of passing Timer objects into
functions
Note the relationship between the classes. Two Display
objects
are used as member data in the Timer class declaration -- they are
named hours and minutes (these are variables).
class Timer
{
public:
// public member functions
private:
// Display objects declared as private data of a Timer object
Display hours, minutes;
};
This is the "has-a" relationship -- a Timer object "has" two objects
of type Display embedded inside of it, as components.
Always pay attention to context, including who is the intented "user"
of any given class. In the case of aggregation, the containing class is
the "user" of the embedded objects.
-
The user of the Timer is the main program (so the main program will
be calling the timer's functions)
-
The user of the Display objects is the Timer object (so the Timer
object will be calling Display functions through the objects hours
and minutes, because those variables are in scope)
Constructors for embedded objects
- When an object is created, its constructor runs, but also must
invoke the constructors of any embedded objects.
- If nothing special is done, it will invoke the default constructor,
if there is one.
- To invoke a constructor with parameters for an embedded object, use
the initialization list
- Note the use of the initialization list on the Timer class
constructor in this example
Another example of classes in a "has-a" relationship:
SodaMachine class
We will see many examples of composition/aggregation in the
future. It's a very common relationship to use in class design.