C++
10-Class Relationships

Class Relationships

In object-oriented programming, class relationships can vary based on the degree of ownership between objects. These relationships include Compositions, Aggregations, and Associations, with each type indicating a different level of coupling between classes. The key to understanding these relationships lies in how objects manage each other’s lifetime and responsibilities.

Compositions

  • A strong "has-a" relationship where one class (composer) completely owns another class (component). The lifetime of the component is bound to the composer, meaning when the composer is destroyed, the component is also destroyed.
  • The component class does not have an independent existence and cannot be shared among multiple composers.
class Person {
    Name name;
    int age;
public:
    Person(const char* name, int age) : name(name), age(age) {}
    // Person manages Name's lifetime.
};

A Person class containing a Name object is an example of composition. Person cannot exist without a Name, and Person is responsible for managing the Name object’s memory and lifecycle.

Aggregations

  • A weaker form of composition where one class (aggregator) uses another class (aggregatee) but does not manage its creation or destruction. The aggregatee can exist independently of the aggregator.
  • The aggregatee can be shared among multiple aggregators.
class Club {
    const Name* members[50];
public:
    void addMember(const Name& member) { /*...*/ }
};

A Club class that contains a list of members, where the members can exist without the club. Club uses Name objects but doesn’t manage their lifecycle. Members exist outside the club and are not destroyed when the Club is destroyed.

Associations

  • The weakest relationship where two classes interact without any ownership or dependency. Both classes can exist independently of each other.
  • Associations are often represented as pointers or references between classes.
class Course {
    Room* assignedRoom;
public:
    void assignRoom(Room& room) { assignedRoom = &room; }
};

A Course and Room relationship where a course can be assigned to a room, but neither is dependent on the other. Course can use Room, but they exist separately. Room does not control the lifecycle of Course, and vice versa.

Key pointers

  • Composition: Strong relationship, one class owns another, and the component’s lifetime is bound to the composer.
  • Aggregation: Weaker relationship, one class uses another, but the aggregatee can exist independently.
  • Association: Weakest relationship, two classes interact without any ownership or dependency.

Prefer composition over inheritance

  • This promotes flexibility and minimizes tight coupling. When objects need to work together, compositions provide a flexible solution where changes to one class (component) don’t heavily affect the other (composer).

Ownership & Responsibility:

  • Composition: Full ownership and responsibility for lifecycle.
  • Aggregation: Partial(Shared) ownership, no responsibility for lifecycle.
  • Association: No ownership or responsibility for lifecycle, purely functional interaction.