Inheritance in C++


Reading time: 50 minutes

Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application. This also provides an opportunity to reuse the code functionality and fast implementation time.
The capability of a class to derive properties and characteristics from another class is called Inheritance. Inheritance is one of the most important feature of Object Oriented Programming.

In other words, Inheritance is a process in which one object acquires all the properties and behaviors of its parent object automatically. In such way, you can reuse, extend or modify the attributes and behaviors which are defined in other class.

  • Sub Class: The class that inherits properties from another class is called Sub class or Derived Class.
  • Super Class:The class whose properties are inherited by sub class is called Base Class or Super class.

When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.

The idea of inheritance implements the is a relationship. For example, mammal IS-A animal, dog IS-A mammal hence dog IS-A animal as well and so on.

Base and Derived Classes

A class can be derived from more than one classes, which means it can inherit data and functions from multiple base classes. To define a derived class, we use a class derivation list to specify the base class(es). A class derivation list names one or more base classes and has the form −

Syntax :-

class derived-class: access-specifier base-class

Where access-specifier is one of public, protected, or private, and base-class is the name of a previously defined class. If the access-specifier is not used, then it is private by default.

Types of Inheritance in C++

In C++, we have 5 different types of Inheritance. Namely,

  1. Single Inheritance
  2. Multiple Inheritance
  3. Hierarchical Inheritance
  4. Multilevel Inheritance
  5. Hybrid Inheritance (also known as Virtual Inheritance)
  6. Multipath Inheritance

1. Single Inheritance

In this type of inheritance one derived class inherits from only one base class. It is the most simplest form of Inheritance.

Syntax:-

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

In the following example ,Employee is the base class and Programmer is the derived class.

Example :-

# include<iostream.h>
using namespace std; 
class Account {  
   public:  
   float salary = 60000;   
 };  
   class Programmer: public Account {  
   public:  
   float bonus = 5000;    
   };       
int main(void) {  
     Programmer p1;  
     cout<<"Salary: "<<p1.salary<<endl;    
     cout<<"Bonus: "<<p1.bonus<<endl;    
    return 0;  
}  

Output

    Salary: 60000
    Bonus: 5000

2. Multiple Inheritance

Multiple Inheritance is a feature of C++ where a class can inherit from more than one classes. i.e one sub class is inherited from more than one base classes.

Syntax :-

class subclass_name : access_mode base_class1, access_mode base_class2, ....
     {
       //body of subclass
     };

Example

In the below example, class 'C' inherits two base classes 'A' and 'B' in a public mode.

# include<iostream.h>
using namespace std; 
class A  
{  
    protected:  
     int a;  
    public:  
    void get_a(int n)  
    {  
        a = n;  
    }  
};  
  
class B  
{  
    protected:  
    int b;  
    public:  
    void get_b(int n)  
    {  
        b = n;  
    }  
};  
class C : public A,public B  
{  
   public:  
    void display()  
    {  
        std::cout<<"The value of a is : "<<a<<std::endl;  
        std::cout<<"The value of b is : "<<b<<std::endl;  
        std::cout<<"Addition of a and b is : "<<a+b;  
    }  
};  
int main()  
{  
   C c;  
   c.get_a(10);  
   c.get_b(20);  
   c.display();  
  
    return 0;  
}  

Output

     The value of a is : 10
     The value of b is : 20
     Addition of a and b is : 30

3. Hierarchical Inheritance

In this type of inheritance, more than one sub class is inherited from a single base class. i.e. more than one derived class is created from a single base class.

Example

In the below example, class vehicle is a base class (i.e. only one base class) where as car & bus are the derived classes (i.e. more than one derived classes).

# include<iostream.h>
using namespace std; 
class Vehicle  
{ 
  public: 
    Vehicle() 
    { 
      cout << "This is a Vehicle" << endl; 
    } 
};  
class Car: public Vehicle 
{ }; 
class Bus: public Vehicle 
{ }; 
int main() 
{   // creating object of sub class will 
    // invoke the constructor of base class 
    Car obj1; 
    Bus obj2; 
    return 0; 
} 

Output

     This is a Vehicle
     This is a Vehicle

4. Multilevel Inheritance

In this type of inheritance the derived class inherits from a class, which in turn inherits from some other class. The Super class for one, is sub class for the other.

Example

In the below example, class Vehicle is a base class which is inherited by class fourWheeler (derived class) which is again inherited by another class Car(derived class) .

# include<iostream.h>
using namespace std; 
// base class 
class Vehicle  
{ 
  public: 
    Vehicle() 
    { 
      cout << "This is a Vehicle" << endl; 
    } 
}; 
class fourWheeler: public Vehicle 
{  public: 
    fourWheeler() 
    { 
      cout<<"Objects with 4 wheels are vehicles"<<endl; 
    } 
}; 
// sub class derived from two base classes 
class Car: public fourWheeler{ 
   public: 
     car() 
     { 
       cout<<"Car has 4 Wheels"<<endl; 
     } 
}; 
int main() 
{    
    //creating object of sub class will 
    //invoke the constructor of base classes 
    Car obj; 
    return 0; 
} 

Output

    This is a Vehicle
    Objects with 4 wheels are vehicles
    Car has 4 Wheels

5. Hybrid Inheritance

Hybrid Inheritance is implemented by combining more than one type of inheritance. For example: Combining Hierarchical inheritance and Multiple Inheritance.

Example

In the below example, class A is a base class which is inherited by class B (derived class) and again there is another base class C . Class D (derived class) inherites both classes B & C.

# include<iostream.h>
using namespace std; 
class A  
{  
    protected:  
    int a;  
    public:  
    void get_a()  
    {  
       std::cout<<"Enter the value of 'a' : " << std::endl;  
       cin >> a;  
    }  
};  
class B : public A   
{  
    protected:  
    int b;  
    public:  
    void get_b()  
    {  
        std::cout << "Enter the value of 'b' : " << std::endl;  
       cin >> b;  
    }  
};  
class C   
{  
    protected:  
    int c;  
    public:  
    void get_c()  
    {  
        std::cout << "Enter the value of c is : " << std::endl;  
        cin >> c;  
    }  
};  
class D : public B, public C  
{  
    protected:  
    int d;  
    public:  
    void mul()  
    {  
         get_a();  
         get_b();  
         get_c();  
         std::cout << "Multiplication of a,b,c is : "<< a*b*c << std::endl;  
    }  
};  
int main()  
{  
    D d;  
    d.mul();  
    return 0;  
}  

Output

    Enter the value of 'a'  : 10              
    Enter the value of 'b'  : 20      
    Enter the value of c is : 30  
    Multiplication of a,b,c is : 6000

6. Multipath Inheritance

It is a derivation of a class from other derived classes, which are derived from the same base class. In this type of inheritance, there involves other inheritance like multiple, multilevel, hierarchical etc.

It is famously known as diamond problem in computer programming.
There is a ambiguity in this type of inheritance .

Example: ambiguity in multipath

Suppose, class D is derived from derived classes B & C directly and from class A indirectly. (hierarchical and multiple)

Both derived classes inherits the features of base class. Hence when we derive a new class by inheriting features form these two classes derived from the same base class, then same features from the first base is inherited to the finally derived class from two paths. This cause ambiguity in accessing first base class members.

# include<iostream.h>  
//ambiguous base class member access
class A
{
private: //..
public:
    void showdata()
    {
        //...
    }
};
class B: virtual public A
{
    //...
};
class C: virtual public A
{
    //..
};
class D: public B, public C
{
public:
    void show_data()
    {
        showdata();//ambiguous which showdata() ?
    }
};

To eliminate this problem, C++ has a mechanism to inherit a single copy of properties from the common base class.

This is done by declaring the base class as virtual while creating derive classes from this base class.

After removing ambiguity :-

#include<iostream.h>   
//removing ambiguity with virtual base class
class A
{
private: //..
public:
    void showdata()
    {
        //...
    }
};
class B: virtual public A
{
    //...
};
class C: virtual public A
{
    //..
};
class D: public B, public C
{
public:
    void show_data()
    {
        showdata();//ambiguous which showdata() 
    }
};

Thus, this introduces the new concept of virtual classes

Use of virtual in multipath inheritance :-

  • In case of multipath inheritance derived class object will have more than one copy of root base class through various paths. To avoid this intermediate classes are declared as virtual classes.

These classes are known as virtual base classes.

Advantage

Code reusability : Now you can reuse the members of your parent class. So, there is no need to define the member again. So less code is required in the class.

Ambiquity Resolution in Inheritance

Ambiguity can be occurred in using the multiple inheritance when a function with the same name occurs in more than one base class.

Let's understand this through an example:

Example

# include<iostream.h>
using namespace std; 
class A  
{  
    public:  
    void display()  
    {  
        std::cout << "Class A" << std::endl;  
    }  
};  
class B  
{  
    public:  
    void display()  
    {  
        std::cout << "Class B" << std::endl;  
    }  
};  
class C : public A, public B  
{  
    void view()  
    {  
        display();  
    }  
};  
int main()  
{  
    C c;  
    c.display();  
    return 0;  
}  

Output

    error: reference to 'display' is ambiguous
    display(); 
  • The above issue can be resolved by using the class resolution operator with the function. In the above example, the derived class code can be rewritten as:
class C : public A, public B  
{  
    void view()  
    {  
        A :: display();         // Calling the display() function of class A.  
        B :: display();         // Calling the display() function of class B.  
  
    }  
};  

An ambiguity can also occur in single inheritance.
Consider the following situation:

class A  
{  
   public:  
void display()  
{  
   cout<<?Class A?;  
}   
} ;  
class B  
{   
  public:  
 void display()  
{  
 cout&lt;&lt;?Class B?;  
}  
} ; 

In the above case, the function of the derived class overrides the method of the base class. Therefore, call to the display() function will simply call the function defined in the derived class. If we want to invoke the base class function, we can use the class resolution operator.

int main()  
{  
    B b;  
   b.display();               // Calling the display() function of B class.  
   b.B :: display();       // Calling the display() function defined in B class.  
}