C++ OOPs: Aggregation

 

Aggregation

This browser does not support PDFs. Please download the PDF to view it: Download PDF.

</embed>

Composition vs aggregation vs association summary

Property Composition Aggregation Association
Relationship type Whole/part Whole/part Otherwise unrelated
Members can belong to multiple classes No Yes Yes
Members existence managed by class Yes No No
Directionality Unidirectional Unidirectional Unidirectional or bidirectional
Relationship verb Part-of Has-a Uses-a

Aggregation in brief

  • To qualify as an aggregation, a whole object and its parts must have the following relationship:
    • The part (member) is part of the object (class)
      • The part (member) can belong to more than one object (class) at a time
      • The part (member) does not have its existence managed by the object (class)
      • The part (member) does not know about the existence of the object (class) (Unidirectional Relationship)
  • When an Aggregation is created, the Aggregation is not responsible for creating the parts.
  • When an Aggregation is destroyed, the Aggregation is not responsible for destroying the parts.

  • Aggregation models has-a relationships (a department has teachers, the car has an engine).

  • In a Composition, we typically add our parts to the composition using normal member variables.
  • In an Aggregation, we also add parts as member variables. However, these member variables are typically either REFERENCES or POINTERS that are used to point at objects that have been created outside the scope of the class.

  • Consequently, an Aggregation usually either takes the objects it is going to point to as Constructor parameters, or it begins empty and the subobjects are added later via access functions(setter()/getter()) or operators.

  • Because these parts exist outside of the scope of the class, when the class is destroyed, the POINTER or REFERENCE member variable will be destroyed (but not deleted). Consequently, the parts themselves will still exist.

  • Summarizing Composition and Aggregation:
    • Compositions:
      • Typically use normal member variables
      • Can use pointer values if the composition class automatically handles allocation/deallocation
      • Responsible for creation/destruction of parts
    • Aggregations:
      • Typically use POINTER or REFERENCE members that point to or reference objects that live outside the scope of the aggregate class
      • Not responsible for creating/destroying parts
  • While aggregations can be extremely useful, they are also potentially more dangerous. Because aggregations do not handle deallocation of their parts, that is left up to an external party to do so.
  • For this reason, compositions should be favored over aggregations.

  • In Aggregation, the relationship is always Unidirectional.

Sample Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <string>
#include <iostream>

class Teacher
{
private:
    std::string m_name;

public:
    Teacher(std::string name)
        : m_name(name)
    {
    }
 
    std::string getName() { return m_name; }
};
 
class Department
{
private:
    Teacher *m_teacher; // This dept holds only one teacher for simplicity, but it could hold many teachers
 
public:
    Department(Teacher *teacher = nullptr)
        : m_teacher(teacher)
    {
      std::cout << "Department has a Teacher named " << teacher->getName() << std::endl;
    }
};
 
int main()
{
    // Create a teacher outside the scope of the Department
    Teacher *teacher = new Teacher("Bob"); // create a teacher
    {
        // Create a department and use the constructor parameter to pass
        // the teacher to it.
        Department dept(teacher);
 
    } // dept goes out of scope here and is destroyed
 
    // Teacher still exists here because dept did not delete m_teacher
 
    std::cout << teacher->getName() << " still exists!" << std::endl;
 
    delete teacher;
 
    return 0;
}