Difference Between Containership And Inheritance In C++ - C++ Programming Tutorial
C++ Course / Inheritance / Difference Between Containership And Inheritance In C++

Difference Between Containership And Inheritance In C++

BLUF: Mastering Difference Between Containership And Inheritance In C++ is a critical step in becoming a proficient C++ developer. This lesson provides a deep dive into the syntax, performance considerations, and real-world applications of this concept.
Key Performance Insight: Difference Between Containership And Inheritance In C++

C++ is renowned for its efficiency. Learn how Difference Between Containership And Inheritance In C++ enables low-level control and high-performance computing in the tutorial below.

In C++, two fundamental concepts are inheritance and composition, which define relationships between classes. However, they serve different purposes and have distinct impacts on the structure and design of a program.

In this tutorial, you will explore the concepts of containership and inheritance in C++. Prior to delving into their distinctions, it is essential to understand both containership and inheritance along with their respective syntax, characteristics, and illustrative instances.

What is the Containership?

Creating instances of a class within another class is commonly referred to as composition or containership. The class that is being used is often referred to as the "contained" or "component" class, whereas the class that holds the object is known as the "container" or "composite" class.

Syntax:

It has the following syntax:

Example

class ComponentClass
{
    // ... (attributes and methods of the component class)
};
class ContainerClass
{
private:
    ComponentClass componentObject; // Composition: Container has a Component
    // ... (other members and methods of the container class)
};

Parameters:

  • ComponentClass: ComponentClass represents a component which has its collection of properties and functions. It contains a particular feature or action.
  • ContainerClass: ContainerClass represents the composition of the class, which demonstrates the presence of a ComponentClass object as a private member ( componentObject ).
  • Features of the Containership:

There are several features of the containership in C++. Some main features of the containership are as follows:

  • Has-A Relationship: A "has-a" relationship between classes is represented by a containership. One of the container class members is an object from another class.
  • Code Reusability: It encourages code reusability by allowing a class use another class's functionality without dealing with inheritance's complexities.
  • Flexibility: It offers more flexibility to alter the system's behaviour while running. It is possible to create and replace objects dynamically.
  • Control: The lifetime and initialization of the enclosed class object are directly under the power of the container class.
  • No Automatic Upcasting: No implicit type hierarchy is created, and there is no automatic upcasting.
  • Example:

Let's consider an example to demonstrate the concept of Containership in C++.

Example

#include <iostream>
#include <string>
// Car class
class Car {
public:
    Car(std::string model) : model(model) {}
    void start() {
        std::cout << "Car " << model << " started." << std::endl;
    }
    void stop() {
        std::cout << "Car " << model << " stopped." << std::endl;
    }
private:
    std::string model;
};
// Driver class containing a Car object
class Driver {
public:
    Driver(std::string name, std::string carModel) : name(name), car(carModel) {}
    void drive() {
        std::cout << name << " is driving." << std::endl;
        car.start();
    }
    void park() {
        car.stop();
        std::cout << name << " parked the car." << std::endl;
    }
private:
    std::string name;
    Car car;
};
int main() {
    // Creating a Driver object with a Car
    Driver john("John", "Sedan");
    // John drives and parks the Car
    john.drive();
    john.park();
    return 0;
}

Output:

Output

John is driving.
Car Sedan started.
Car Sedan stopped.
John parked the Car.

Explanation:

  • In this example, the Car class represents a simple car with a model. It has a constructor that initializes the model of the Car.
  • It has two member functions, start and stop , which print messages indicating that the Car has started or stopped. The Driver class represents a driver with a name and driving a car.
  • After that, it has a constructor that takes the driver's name and the model of the Car, and it initializes a Car object named Car.
  • The member functions to drive and park simulated as the driver driving and parking the car. The drive function prints a message indicating the driver is driving and then calls the start function of the associated Car object. The park function calls the stop function of the associated Car object and prints a message indicating that the driver parked the Car.
  • In the main function , a Driver object named john is created with the name "John" and a car model "Sedan" .
  • After that, the drive and park functions of the john object are called, simulating John driving and parking the Car.
  • The program ends by returning 0 from the main function.
  • This code illustrates the concept of containership in C++, where the Driver class contains a member variable of the Car type. It demonstrates a simple relationship between a driver and a car, where the driver can perform actions like driving and parking the associated Car.
  • What is the Inheritance?

In programming, inheritance involves passing on attributes and actions from a current class (referred to as the base or parent class) to a fresh class (known as the derived or child class). This process allows the derived class to build upon or customize the features of the base class.

Syntax:

It has the following syntax:

Example

class subclass_name : access_mode base_class_name {
    // body of subclass
};

Parameters:

  • class: A keyword that denotes a class declaration.
  • subclass_name: The derived class name that is being defined.
  • (Colon): It indicates the start of the access specifier and base class list.
  • base class name: It is the base class that is being inherited's name.
  • {}: It encloses the members and body of the derived class
  • Access Specifiers:

  • public: In the derived class, the public base class members are still public.
  • protected: Members of the public and protected base classes gain protection in the derived class.
  • private: In the derived class, public and protected base class members turn private.
  • Features of the Inheritance:

There are several features of the Inheritance in C++. Some main features of the Inheritance are as follows:

  • Is-A Relationship: One example of an "is-a" relationship is inheritance. A subclass of the base class is the derived class.
  • Code Reusability: It encourages code reusability by allowing the derived class that inherit the base class's members (methods and attributes).
  • Polymorphism: It facilitates polymorphism, permitting the utilisation of derived class objects in situations where base class objects are anticipated.
  • Automatic Upcasting: This feature enables an object of the derived class to be referenced from a pointer or to the base class.
  • Runtime Binding: It enables dynamic dispatch by supporting runtime binding via virtual functions.
  • Example:

Let's consider an example to demonstrate the concept of Inheritance in C++.

Example

#include <iostream>
// Vehicle class (base class)
class Vehicle
{
public:
    void startEngine()
    {
        std::cout << "Engine started.\n";
    }
    void drive() 
    {
        std::cout << "The vehicle is driving.\n";
    }
};
// Car class (derived class using inheritance)
class Car : public Vehicle
{
public:
    void honk()
    {
        std::cout << "The car is honking.\n";
    }
};
int main() 
{
    Car myCar;
    // Accessing both Vehicle and Car functionality through inheritance
    myCar.startEngine();
    myCar.drive();
    myCar.honk();
    return 0;
}

Output:

Output

Engine started.
The vehicle is driving.
The Car is honking.

Explanation:

  • In this example, the program defines the base class Vehicle . StartEngine and drive are its two public member operations. A message showing that the engine has started is printed by the startEngine function, and the drive function prints a message indicating that the vehicle is in drive.
  • After that, a derived class called Car is defined using a public inheritance from the Vehicle base class. This implies that the Car class inherits the public and protected members of the Vehicle class. The new public member function honk, introduced by the Car class, which produces a message indicating that the Car is honking.
  • An object of the Car class with the name myCar is created in the main method. Next, the program illustrates the usage of inheritance by using member functions from both the base class (Vehicle) and the derived class (Car),
  • The startEngine function inherited from the Vehicle base class is called by startEngine .
  • After that, MyCar calls the drive function inherited from the Vehicle base drive .
  • myCar.honk; invokes the Car class's unique honk function.
  • This output illustrates that the Car class inherits the functionality of the Vehicle class and extends it with its own specific functionality.
  • Key Differences between the Containership and Inheritance:

There are various distinctions between Containership and Inheritance in C++. Here are some key variances between Containership and Inheritance.

1. Nature of Relationship

Containership (Composition):

An instance of a class can be present within another class.

Relationship: A "Has-a" connection where an object of one class is a part of another class.

Typically, the container class possesses the contained item.

Flexibility is enhanced through the capability to make runtime adjustments to the encapsulated object.

Inheritance:

A class acquires attributes and properties from another class through the process of inheritance.

Relationship: The subclass is an altered version of the superclass, indicated by the "Is-a" association.

Ownership: There is no ownership connection; the subclass does not control the lifespan of the superclass.

Flexibility: It is generally less versatile as the connection is determined during compilation.

2. Code Reusability

Containership (Composition): It allows a class to hold instances that are objects of different classes, encouraging the reuse of code.

Inheritance promotes code reusability by allowing a class to acquire characteristics and functionalities from a parent class.

3. Flexibility

Containership (Composition): It provides loose interconnection and adaptability. Objects can be adjusted during runtime, allowing for dynamic assembly.

Inheritance: Establishing a more structured framework, inheritance introduces a relationship where changes made to the base class can affect all its derived classes.

4. Access to Members

Contented class members are not directly visible outside the container class but can be accessed via the container class.

Inheritance: Members of the base class can be accessed in the derived class based on the access specifiers (public, protected, or private).

5. Complexity and Coupling

Containership (Composition): It commonly results in a modular design by decreasing the reliance between classes.

Higher coupling can be a potential outcome of inheritance, especially when changes made to the parent class affect multiple child classes.

6. Hierarchy

Containership (Composition): It establishes a level structure with minimal class dependencies.

Inheritance: Establishing a hierarchical structure, inheritance forms a unique relationship between parent and child elements.

7. Static vs Dynamic Binding

Containership (Composition): It facilitates dynamic linking and could be more appropriate for changes implemented during program execution.

Inheritance enables compile-time static binding, while polymorphism utilizing virtual functions allows for dynamic behavior.

8. Encapsulation

Containership (Composition): The containing class encompasses the details of the contained class through containership.

Inheritance allows the subclass to utilize the interface of the superclass.

9. Usage Scenarios

When aiming to build objects by combining simpler objects or when classes lack an "is-a" relationship, utilizing containership (composition) is the most effective approach.

Utilizing inheritance can be beneficial when aiming to model a hierarchy that includes common attributes and behaviors, establishing an evident "is-a" connection.

10. Constructor and Destructor Invocations

For every class, there is a constructor and a destructor present as part of its containership.

Due to inheritance, constructors and destructors are invoked starting from the base class and proceeding to the class with the highest level of derivation in a specific sequence.

Input Required

This code uses input(). Please provide values below:

Logic Practice
Install Logic Practice
Add to home screen for a faster app-like experience