Understanding Composition in C++: A Beginner's Guide to Class Relationships
Introduction
Composition is the strongest form of the "has-a" relationship in Object-Oriented Programming (OOP). It represents a whole-part relationship in which the parent object completely owns and manages its child objects.
Unlike aggregation, where child objects exist independently, composition establishes strong ownership. The child objects are created as part of the parent object and cannot exist without it. When the parent object is created, its child objects are automatically created. Similarly, when the parent object is destroyed, all of its child objects are automatically destroyed as well.
In C++, composition is typically implemented by declaring one class as a normal data member inside another class. This ensures that the lifetime of the child object is directly tied to the lifetime of its parent.
This document presents two practical examples demonstrating composition relationships in C++.
Example 1: Computer and Processor Relationship
This example demonstrates composition through a computer and its processor. A processor is an integral part of a computer and cannot exist independently within the context of this application.
Program
Explanation
The program defines two classes: Processor and Computer.
The Computer class contains a Processor object as one of its data members. Since the processor is declared directly inside the class rather than through a pointer or reference, the processor becomes an integral part of the computer object.
When a Computer object is created, the constructor of the Processor class executes automatically before the constructor of the Computer class completes. This demonstrates that the processor is created together with its parent object.
When the Computer object goes out of scope, its destructor is executed first, followed immediately by the destructor of the embedded Processor object. This automatic destruction demonstrates the strong ownership relationship that characterizes composition.
The processor cannot exist independently because its lifetime is completely controlled by the computer object.
Example 2: House and Room Relationship
This example demonstrates composition using a house and its rooms. Every room belongs to a specific house, and its existence depends entirely on the house.
Program
Explanation
The Room class represents individual rooms, while the House class represents a complete house.
Instead of storing pointers or references to external room objects, the House class stores a vector containing actual Room objects. These rooms are created internally by the House constructor and become part of the house itself.
Inside the main() function, a dynamically allocated House object is created. During construction, the house automatically creates its rooms and stores them inside the floorPlan vector.
When the House object is deleted, its destructor is automatically executed. As part of the destruction process, the floorPlan vector is also destroyed, which in turn destroys every Room object stored within it.
The rooms cannot continue to exist after the house has been destroyed because they are owned entirely by the house object. This demonstrates the defining characteristic of composition.
Characteristics of Composition
| Property | Description |
|---|---|
| Relationship Type | Represents a strong "has-a" or whole-part relationship. |
| Ownership | The parent object completely owns the child object. |
| Object Lifecycles | Child objects are created and destroyed together with the parent object. |
| Implementation | Implemented by declaring child objects directly as data members of the parent class. |
| Memory Management | Managed automatically by the parent object without requiring separate memory management for child objects. |
Conclusion
Composition is the strongest form of object relationship in Object-Oriented Programming because it establishes complete ownership between the parent and child objects. The parent object creates, manages, and destroys its child objects, ensuring that they cannot exist independently. This strong dependency simplifies memory management, improves encapsulation, and models real-world whole-part relationships effectively. As demonstrated in the Computer–Processor and House–Room examples, composition is implemented in C++ by declaring child objects directly within the parent class, ensuring that their lifecycles remain tightly connected.