Composition and Aggregation in C++

Composition and Aggregation in C++

In Object-Oriented Programming (OOP), Composition and Aggregation describe relationships between classes, specifically how objects are associated with one another. Both are forms of the “has-a” relationship, but they differ in strength and dependency. So in this article we will see the concept of Composition and Aggregation in C++ and also check the difference between Composition and Aggregation.

What is Composition?

Composition represents a strong relationship between two classes. It is used when an object (child) is a part of another object (parent), and the child object cannot exist independently of the parent. The lifecycle of the child object is tied to the lifecycle of the parent. If the parent object is destroyed, the child object is also destroyed.

Key Characteristics of Composition:

  1. Strong Dependency:
    • The parent object owns the child object. The child cannot exist without the parent.
  2. Lifecycle Management:
    • The lifecycle of the child object is bound to the parent. Destroying the parent automatically destroys the child.
  3. Real-World Example:
    • A car and its engine. The engine is a part of the car, and without the car, the engine serves no purpose.

Example Code: Composition in C++

#include <iostream>
#include <string>
using namespace std;
// Engine class representing a part of a Car
class Engine {
private:
string type;
public:
// Constructor to initialize the engine type
Engine(const string& type) : type(type) {}
void start() const {
cout << "Engine of type " << type << " is starting." << endl;
}
string getType() const {
return type;
}
};
// Car class using Composition
class Car {
private:
Engine engine; // Car "has-an" Engine (composition relationship)
public:
// Constructor to initialize the car with an engine
Car(const string& engineType) : engine(engineType) {}
void startCar() const {
cout << "Car is starting." << endl;
engine.start(); // Car depends on the engine's functionality
}
void showDetails() const {
cout << "Car with engine type: " << engine.getType() << endl;
}
};

int main() {
// Create a car with an engine
Car car("V8");
// Start the car and display its details
car.startCar();
car.showDetails();
return 0;
}

Explanation of Composition Code:

  • Engine Class:
    Represents an engine with:
    A type property to store the type of engine.
    Methods getType() and start() to provide engine-specific functionalities.
  • Car Class:
    Represents a car containing an Engine object. It has:
    A constructor to initialize the Car object with an Engine.
    A method startCar() to start the car, which also starts the engine.
    A method showDetails() to display the car’s engine type.
  • Key Points:
    The Car class fully owns the Engine object.
    The Engine object is created when the Car object is initialized and destroyed when the Car object is destroyed.

What is Aggregation?

Aggregation represents a weaker relationship between two classes. It is used when an object (child) is associated with another object (parent), but the child object can exist independently of the parent. The lifecycle of the child object is not tied to the lifecycle of the parent.

Key Characteristics of Aggregation:

  1. Weak Dependency:
    • The parent object holds a reference to the child object, but the child can exist without the parent.
  2. Independent Lifecycle:
    • The child object’s lifecycle is independent of the parent. Destroying the parent does not affect the child.
  3. Real-World Example:
    • A house and its residents. The residents can exist independently of the house.

Example Code: Aggregation in C++

#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Person class representing a resident
class Person {
private:
string name;
public:
// Constructor to initialize the person's name
Person(const string& name) : name(name) {}
string getName() const {
return name;
}
};
// House class containing a list of residents (Aggregation)
class House {
private:
vector<Person> residents; // A house "has-a" list of residents
public:
// Method to add a resident to the house
void addResident(const Person& person) {
residents.push_back(person);
}
// Method to display all residents
void showResidents() const {
cout << "House residents:" << endl;
for (const auto& person : residents) {
cout << person.getName() << endl;
}
}
};
int main() {
// Create Person objects
Person p1("Alice");
Person p2("Bob");
// Create a House object
House house;
// Add residents to the house
house.addResident(p1);
house.addResident(p2);
// Display residents of the house
house.showResidents();
return 0;
}

Explanation of Aggregation Code:

  • Person Class:
    Represents a person with a name. It has:
    A constructor to initialize the name.
    A method getName() to retrieve the person’s name.
  • House Class:
    Represents a house containing multiple residents (a collection of Person objects). It has:
    A method addResident() to add a Person object to the house.
    A method showResidents() to display the names of all residents.
  • Key Points:
    The House class does not own Person objects. It merely stores references (in this case, values) to existing Person objects.
    Person objects (p1, p2) exist independently of the House object.

Benefits of Using Composition and Aggregation

  1. Flexibility:
    Both approaches provide flexibility in structuring relationships between classes, promoting modular design.
  2. Reusability:
    Classes designed with Composition or Aggregation can be reused in different contexts without modification.
  3. Encapsulation:
    Composition and Aggregation encourage encapsulating functionality in smaller classes, improving code readability.
  4. Maintainability:
    Breaking down systems into smaller, related components makes them easier to maintain and extend.

Difference in Composition and Aggregation:

AspectCompositionAggregation
OwnershipThe parent object owns the child object.The parent object holds a reference to the child object.
Lifecycle DependencyThe child object’s lifecycle is tied to the parent.The child object’s lifecycle is independent of the parent.
Strength of RelationshipStrongWeak
ExampleA car “has-an” engine.A house “has-a” resident.

Key Differences:

  1. Ownership:
    • In Composition, the parent object owns the child object.
    • In Aggregation, the parent object does not own the child object, and the child can exist independently.
  2. Lifecycle Management:
    • In Composition, when the parent object is destroyed, the child object is also destroyed automatically.
    • In Aggregation, the child object’s lifecycle is independent, and destroying the parent object does not affect the child object.
  3. Relationship Strength:
    • Composition is a stronger relationship, indicating that the child is an integral part of the parent.
    • Aggregation is a weaker relationship, suggesting that the child can exist on its own without the parent.

Real-World Analogies:

  • Composition: A heart is a part of the human body. Without the body, the heart cannot exist.
  • Aggregation: A book belongs to a library, but it can be removed from the library and still exist as an independent object.

Choosing Between Composition and Aggregation:

The choice between Composition and Aggregation depends on the level of dependency between the objects. If the child object’s lifecycle depends on the parent, then Composition is the right choice. If the child object can exist independently of the parent, then Aggregation is more appropriate.

By understanding and correctly implementing Composition and Aggregation, developers can create more flexible, maintainable, and logically structured software systems. These concepts help in modeling real-world scenarios accurately and ensure better code organization and reuse.

Summary

In object-oriented programming (OOP), Composition and Aggregation are two key concepts that describe how classes relate to each other. Both represent a “has-a” relationship, but they differ in the strength of the relationship and how objects are dependent on one another.

  • Composition represents a strong relationship where one object (the parent) completely owns and controls the lifecycle of another object (the child). The child object cannot exist without the parent object. For example, a Car “has-an” Engine, and the engine’s existence is tightly bound to the car.
  • Aggregation, on the other hand, represents a weaker relationship. While the parent object holds a reference to the child object, the child object can exist independently of the parent. For example, a House “has-a” Resident, but the resident can live elsewhere, independent of the house’s existence.

Key Takeaways

  1. Composition is used when objects are tightly coupled, and their lifecycles are interdependent.
  2. Aggregation is used when objects are loosely coupled and can exist independently.
  3. Understanding the differences between Composition and Aggregation helps design better and more flexible class relationships, leading to cleaner and more maintainable code.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this:
Verified by MonsterInsights