Inheritance in C++

Mannan Ul Haq
0

Inheritance is a fundamental concept in object-oriented programming (OOP) that allows you to create new classes based on existing classes. In C++, inheritance enables the creation of derived classes (also known as subclasses or child classes) that inherit the properties and behavior of a base class (also known as a superclass or parent class). This relationship between classes is often referred to as an "is-a" relationship, indicating that a derived class is a specific type of the base class.


Syntax:

class { derived_class_name } : {visibility_mode} {base_class_name}


To illustrate inheritance, consider the following example:


class Shape
{
protected:
    int width;
    int height;

public:

    void setDimensions(int w, int h)
    {
        width = w;
        height = h;
    }
};

class Rectangle : public Shape
{
public:

    int getArea()
    {
        return width * height;
    }
};

int main()
{
    Rectangle rect;
    rect.setDimensions(5, 3);

    int area = rect.getArea();

    return 0;
}


In this example, we have a base class `Shape` and a derived class `Rectangle`. The `Rectangle` class inherits publicly from the `Shape` class using the `public` access specifier. This means that all public and protected members of the `Shape` class are accessible in the `Rectangle` class.


Inheritance allows code reuse, as the derived class inherits the attributes and behaviors of the base class. It facilitates the creation of a hierarchical structure of classes, where each derived class specializes or adds functionality to the base class. This inheritance hierarchy can be extended further by creating additional derived classes from existing derived classes.


Visibility Modes:

Inheritance in C++ involves the use of access specifiers to control the visibility and accessibility of inherited members in the derived class. C++ provides three access specifiers: `public`, `protected`, and `private`.


1. Public Inheritance:

In public inheritance, the public and protected members of the base class become public and protected members, respectively, in the derived class. The derived class and any external code can access the public members of the base class.


Example:


class Base
{
public:
    int publicVar;

protected:
    int protectedVar;
};

class Derived : public Base
{
public:

    void accessBaseMembers()
    {
        publicVar = 10;        // Accessible
        protectedVar = 20;    // Accessible within derived class
    }
};

int main()
{
    Derived obj;
    obj.publicVar = 30;     // Accessible

    //obj.protectedVar = 40; // Not accessible from outside the derived class

    return 0;
}


2. Protected Inheritance:

Protected inheritance is less commonly used but still worth understanding. In protected inheritance, the public and protected members of the base class become protected members in the derived class.


Example:


class Base
{
public:
    int publicVar;

protected:
    int protectedVar;
};

class Derived : protected Base
{
public:

    void accessBaseMembers()
    {
        publicVar = 10;        // Accessible within derived class
        protectedVar = 20;    // Accessible within derived class
    }
};

int main()
{
    Derived obj;

    //obj.publicVar = 30;     // Not accessible from outside the derived class
    //obj.protectedVar = 40;  // Not accessible from outside the derived class

    return 0;
}


3. Private Inheritance:

Private inheritance is used when you want to inherit the members of the base class as private members in the derived class. Private members are not accessible from outside the derived class or any further derived classes.


Example:


class Base
{
public:
    int publicVar;

private:
    int privateVar;
};

class Derived : private Base
{
public:

    void accessBaseMembers()
    {
        publicVar = 10;        // Accessible within derived class
        //privateVar = 20;     // Not accessible within derived class
    }
};

int main()
{
    Derived obj;

    //obj.publicVar = 30;     // Not accessible from outside the derived class
    //obj.privateVar = 40;    // Not accessible from outside the derived class

    return 0;
}


Types of Inheritance:

There are several types of inheritance that you can use to establish different relationships between the base and derived classes. Let's explore the most commonly used types of inheritance:


1. Single Inheritance:

Single inheritance is the most basic and commonly used type of inheritance. In single inheritance, a derived class inherits from a single base class.

Example:


class Base
{
    // Base class members
};

class Derived : public Base
{
    // Derived class members
};


2. Multiple Inheritance:

Multiple inheritance allows a derived class to inherit from multiple base classes. This means that the derived class can combine the features and behaviors of multiple base classes.

Example:


class Base1
{
    // Base class 1 members
};

class Base2
{
    // Base class 2 members
};

class Derived : public Base1, public Base2
{
    // Derived class members
};


3. Multilevel Inheritance:

Multilevel inheritance involves a chain of inheritance, where a derived class becomes the base class for another derived class. It allows the creation of a hierarchy of classes with each derived class inheriting properties and behaviors from its immediate base class.

Example:


class Base
{
    // Base class members
};

class Derived1 : public Base
{
    // Derived class 1 members
};

class Derived2 : public Derived1
{
    // Derived class 2 members
};


4. Hierarchical Inheritance:

Hierarchical inheritance involves multiple derived classes inheriting from a single base class. In this type of inheritance, different derived classes extend the functionality of the base class in different ways, creating a hierarchy of classes.

Example:


class Base
{
    // Base class members
};

class Derived1 : public Base
{
    // Derived class 1 members
};

class Derived2 : public Base
{
    // Derived class 2 members
};


5. Hybrid Inheritance:

Hybrid inheritance combines multiple types of inheritance. It is a combination of single, multiple, and multilevel inheritances. Hybrid inheritance allows for great flexibility in class design, but it can also become complex and harder to manage.

Example:


class Base
{
    // Base class members
};

class Derived1 : public Base
{
    // Derived class 1 members
};

class Derived2 : public Derived1
{
    // Derived class 2 members
};

class Derived3 : public Base, public Derived1
{
    // Derived class 3 members
};


Constructor Call Sequence in Inheritance:

When you have a derived class that inherits from a base class, the constructor call sequence determines the order in which the constructors are executed during the creation of an object. The constructor call sequence ensures that the base class is initialized before the derived class.

Here's a simplified explanation of the constructor call sequence:

1. Base Class Constructors:

The constructors of the base classes are called first. If there are multiple base classes, they are initialized in the order they are listed in the derived class's inheritance declaration. Each base class is responsible for initializing its own data members.

2. Derived Class Constructor:

After the base class constructors are executed, the constructor of the derived class is called. The derived class constructor initializes the data members specific to the derived class.

By following this sequence, the derived class can rely on the fully constructed base class when initializing its own members.

Let's consider an example to explain the constructor call sequence in inheritance:

#include <iostream>
using namespace std;

class Base
{
private:
    int baseData;

public:
    Base(int data)
    {
        baseData = data;
        cout << "Base Constructor with data: " << baseData << endl;
    }
};

class Derived : public Base
{
private:
    int derivedData;

public:
    Derived(int data1, int data2) : Base(data1)
    {
        derivedData = data2;
        cout << "Derived Constructor with data: " << derivedData << endl;
    }
};

int main()
{
    Derived derivedObj(10, 20);
    return 0;
}

Output:

Base Constructor with data: 10
Derived Constructor with data: 20

When an object of the derived class `Derived` is created with the statement `Derived derivedObj(10, 20);`, the constructor call sequence is as follows:

1. The parameterized constructor of the base class `Base` is called with the argument `10`. It outputs "Base Constructor with data: 10".

2. After the base class is initialized, the parameterized constructor of the derived class `Derived` is called with the arguments `20`. It outputs "Derived Constructor with data: 20".

By passing the appropriate arguments to the constructors, you can initialize the data members of both the base and derived classes.


Tags

Post a Comment

0Comments

Post a Comment (0)

#buttons=(Accept !) #days=(20)

Our website uses cookies to enhance your experience. Check Now
Accept !