To implement aggregation in C++, we need to have a variable that gives us access to some memory without owning it. That means we canβt use a regular variable, like a Point m_center, as regular variables βownβ a chunk of memory. When a regular variable goes out of scope, the variable it names goes away. Pointers (and references) are different. A pointer just names a place in memory where we store a memory address (hopefully the address of some useful piece of data). When the pointer goes away, all that is lost is that copy of the address. The data at that address is not lost.
A βpointerβ variable (like p in int* p = &x;) may or may not own the memory it points at. Until we learn about dynamic allocation, we will assume pointers do NOT own the memory they point at.
So to implement aggregation, we need to use pointers or references. There are some limitation that come with references: you canβt have a null reference and you have to initialize references when they are created. So if we chose reference variables, we could not have a Person with no spouse (a null value for a spouse). And we would have to use the initialization list to make sure that the spouse was initialized as the space for it was allocated. To avoid these limitations and keep things consistent even in situations where they might not matter, we will always use pointers to implement aggregation.
We also could implement composition using pointers if we made sure that each container object pointed to a unique object and that those contained objects went away when their container did. We will avoid that complication.
A Circle class built using aggregation will be very similar to the composition version, but will store a pointer to a Point instead of a Point. A simplified version of this new Circle class might look like:
We have to pass an existing Point object to the Circle constructor because the Circle will not have its own storage for a Point. Instead, it will just store the address of a Point, which means that Point must already exist elsewhere in memory.
A memory diagram for the main function after all of the Circles are constructed would look lime the image below. c1 and c2 donβt hold their own Point objects, they hold the memory address of p1.
This means, that any change to p1 will be βseenβ by the two Circle objects. We can see this in the last few lines of the program above. Shifting Point p1 affects the center of both c1 and c2 because they both use the actual Point p1 as their center.
This is a critical distinction between aggregation and composition. If we made two circles from a Point p1 with the composition version of Circle, each Circle would make its own copy of the data from p1 and store that data.
If we modeled aggregation between a Person and their best friend (also a Person) with references instead of pointers, what is something we could not do?