Composition is a design principle in object-oriented programming (O O P) that represents a "has-a" relationship between two classes. It is a special type of aggregation, where one class owns or contains objects of another class, and the contained objects typically cannot exist without the containing class. In other words, when the parent class (or the container) is destroyed, the contained objects are also destroyed.
Composition is used when the contained object lifecycle is dependent on the lifecycle of the container object.
Aggregation is a looser relationship, where the part can exist independently of the whole. For example, a Library can contain Books, but the Books could exist independently of the Library.
Composition, on the other hand, represents a stronger relationship, where the part cannot exist without the whole. For example, a Car has an Engine, and the Engine cannot exist independently of the Car. If the Car is destroyed, the Engine will also be destroyed.
Let's take an example of a Car and an Engine to demonstrate composition.
In this case, a Car has an Engine, and an Engine cannot exist without the Car. If the Car object is destroyed, its Engine should also be destroyed.
#include <iostream>
#include <string>
using namespace std;
class Engine {
public:
string engineType;
// Constructor
Engine(const string& type) : engineType(type) {
cout << "Engine created: " << engineType << endl;
}
// Destructor
~Engine() {
cout << "Engine destroyed: " << engineType << endl;
}
};
class Car {
private:
Engine engine; // Composition: Car has an Engine
public:
// Constructor that initializes the Engine
Car(const string& engineType) : engine(engineType) {
cout << "Car created!" << endl;
}
// Destructor
~Car() {
cout << "Car destroyed!" << endl;
}
// Function to display car information
void display() {
cout << "This car has an " << engine.engineType << " engine." << endl;
}
};
int main() {
// Creating a Car object will also create an Engine object
Car car("V8");
car.display();
// When the car object goes out of scope, both car and engine are destroyed.
return 0;
}
Car class has an Engine as a member variable. This is the composition relationship, meaning that the Car is responsible for the Engine's creation and destruction.Car object is created, it initializes the Engine object via the Car constructor. The Engine's constructor prints a message indicating the engine type.Car object goes out of scope, its destructor is called, which implicitly calls the Engine's destructor (since the Engine is a part of the Car). This leads to the destruction of the Engine object.Car is destroyed at the end of the program (i.e., when it goes out of scope), the Engine is also destroyed automatically.Engine created: V8
Car created!
This car has an V8 engine.
Car destroyed!
Engine destroyed: V8
Car object could have a V6 engine or a V8 engine).While both composition and inheritance are used to establish relationships between classes, they differ in their intent and use cases:
Dog is an Animal), whereas composition models a "has-a" relationship (e.g., a Car has an Engine).In object-oriented design, knowing when to use composition is crucial for building flexible, maintainable, and effective systems.
Open this section to load past papers