A Complete Look at the Types of Inheritance in C++

Inheritance is one of four pillars of Object-Oriented Programming (OOPs). It is a feature that enables a class to acquire properties and characteristics of another class. Inheritance allows you to reuse your code since the derived class or the child class can reuse the members of the base class by inheriting them. Consider a real-life example to clearly understand the concept of inheritance. A child inherits some properties from his/her parents, such as the ability to speak, walk, eat, and so on. But these properties are not especially inherited in his parents only. His parents inherit these properties from another class called mammals. This mammal class again derives these characteristics from the animal class. Inheritance works in the same manner.

During inheritance, the data members of the base class get copied in the derived class and can be accessed depending upon the visibility mode used. The order of the accessibility is always in a decreasing order i.e., from public to protected. There are mainly five types of Inheritance in C++ that you will explore in this article. They are as follows:

  • Single Inheritance
  • Multiple Inheritance
  • Multilevel Inheritance
  • Hierarchical Inheritance
  • Hybrid Inheritance

What Are Child and Parent classes?

To clearly understand the concept of Inheritance, you must learn about two terms on which the whole concept of inheritance is based - Child class and Parent class.

  • Child class: The class that inherits the characteristics of another class is known as the child class or derived class. The number of child classes that can be inherited from a single parent class is based upon the type of inheritance. A child class will access the data members of the parent class according to the visibility mode specified during the declaration of the child class.

  • Parent class: The class from which the child class inherits its properties is called the parent class or base class. A single parent class can derive multiple child classes (Hierarchical Inheritance) or multiple parent classes can inherit a single base class (Multiple Inheritance). This depends on the different types of inheritance in C++.

The syntax for defining the child class and parent class in all types of Inheritance in C++ is given below:

class parent_class

{

    //class definition of the parent class

};

class child_class : visibility_mode parent_class

{

   //class definition of the child class

};

Syntax Description

  • parent_class: Name of the base class or the parent class.

  • child_class: Name of the derived class or the child class.
  • visibility_mode: Type of the visibility mode (i.e., private, protected, and public) that specifies how the data members of the child class inherit from the parent class. 

Stand Out From Your Peers this Appraisal Season

Start Learning With Our FREE CoursesEnroll Now
Stand Out From Your Peers this Appraisal Season

Why and When to Use Inheritance?

Inheritance makes the programming more efficient and is used because of the benefits it provides. The most important usages of inheritance are discussed below: 

  1. Code reusability: One of the main reasons to use inheritance is that you can reuse the code. For example, consider a group of animals as separate classes - Tiger, Lion, and Panther. For these classes, you can create member functions like the predator() as they all are predators, canine() as they all have canine teeth to hunt, and claws() as all the three animals have big and sharp claws.  Now, since all the three functions are the same for these classes, making separate functions for all of them will cause data redundancy and can increase the chances of error. So instead of this, you can use inheritance here. You can create a base class named carnivores and add these functions to it and inherit these functions to the tiger, lion, and panther classes.
  2. Transitive nature: Inheritance is also used because of its transitive nature. For example, you have a derived class mammal that inherits its properties from the base class animal. Now, because of the transitive nature of the inheritance, all the child classes of ‘mammal’ will inherit the properties of the class ‘animal’ as well. This helps in debugging to a great extent. You can remove the bugs from your base class and all the inherited classes will automatically get debugged.

Visibility Modes

The visibility mode specifies how the features of the base class will be inherited by the derived class. There are three types of visibility modes for all types of Inheritance in C++:

  • Public Visibility Mode:

In the public visibility mode, it retains the accessibility of all the members of the base class. The members specified as public, protected, and private in the base class remain public, protected, and private respectively in the derived class as well. So, the public members are accessible by the derived class and all other classes. The protected members are accessible only inside the derived class and its members. However, the private members are not accessible to the derived class.

The following code snippet illustrates how to apply the public visibility mode in a derived class:

class base_class_1

{

    // class definition

};

class derived_class: public base_class_1

{

    // class definition

};

The following code displays the working of public visibility mode with all three access specifiers of the base class:

class base_class

{

private:

    //class member

    int base_private; 

protected:

    //class member

    int base_protected;

public:

    //class member

    int base_public;

}; 

class derived_class : public base_class

{

private:

    int derived_private;

    // int base_private;

protected:

    int derived_protected;

    // int base_protected;

public:

    int derived_public;

    // int base_public;

}; 

int main()

{

    // Accessing members of base_class using object of the //derived_class:

    derived_class obj;

    obj.base_private;   // Not accessible

    obj.base_protected; // Not accessible

    obj.base_public;    // Accessible

}

types_of_inheritance_in_cpp_1  

In the above example, the derived class inherits the base class as public. The private members are not accessible at all by the derived class. The protected members are only accessible inside the derived class and not accessible outside the class. And the public members are accessible inside and outside the class.

  • Private Visibility Mode: 

In the private visibility mode, all the members of the base class become private in the derived class. This restricts the access of these members outside the derived class. They can only be accessed by the member functions of the derived class. And in this case, the derived class does not inherit the private members. 

The following code snippet illustrates how to apply the private visibility mode in a derived class:

class base_class_1

{

    // class definition

};

class derived_class: private base_class_1

{

    // class definition

};

The following code displays the working of private visibility mode with all three access specifiers of the base class:

class base_class

{

private:

    //class member

    int base_private;

protected:

    //class member

    int base_protected;

public:

    //class member

    int base_public;

};

class derived_class : private base_class

{

private:

    int derived_private;

    // int base_private;

    // int base_protected;

    // int base_public

protected:

    int derived_protected;

 public:

    int derived_public;

}; 

int main()

{

    // Accessing members of base_class using object of the derived_class:

    derived_class obj;

    obj.base_private;   // Not accessible

    obj.base_protected; // Not accessible

    obj.base_public;    // Not Accessible

}

types_of_inheritance_in_cpp_2.  

In the above example, the derived class inherits the base class privately. So, all the members of the base class have become private in the derived class. The error is thrown when the object of the derived class tries to access these members outside the class.

  • Protected Visibility Mode:

In the protected visibility mode, all the members of the base class become protected members of the derived class. These members are now only accessible by the derived class and its member functions. These members can also be inherited and will be accessible to the inherited subclasses. However, objects of the derived classes cannot access these members outside the class.

The following code snippet illustrates how to apply the protected visibility mode in a derived class:

class base_class_1

{

    // class definition

};

class derived_class: protected base_class_1

{

    // class definition

};

The following code displays the working of protected visibility mode with all three access specifiers of the base class:

class base_class

{

private:

    //class member

    int base_private;

protected:

    //class member

    int base_protected;

public:

    //class member

    int base_public;

};

class derived_class : protected base_class

{

private:

    int derived_private;

    // int base_private;

protected:

    int derived_protected;

    // int base_protected;

    // int base_public

public:

    int derived_public;

}; 

int main()

{

    // Accessing members of base_class using object of the derived_class:

    derived_class obj;

    obj.base_private;   // Not accessible

    obj.base_protected; // Not accessible

    obj.base_public;    // Not Accessible

}

types_of_inheritance_in_cpp_3. 

In the above example, the derived class inherits the base class in protected mode. All the members of the base class are now only accessible inside the derived class and not anywhere outside the class. So it throws an error when the object obj of the derived class tries to access these members outside the class.

The following table illustrates the control of the derived classes over the members of the base class in different visibility modes:

 BASE CLASS

DERIVED CLASS

DERIVED CLASS

DERIVED CLASS

PUBLIC

PROTECTED

PRIVATE

PUBLIC 

Public

Protected

Private

PROTECTED

Protected

Protected

Private

PRIVATE

Not Inherited / Remains Private

Not Inherited / Remains Private

Not Inherited / Remains Private

Types of inheritance in C++

There are five types of inheritance in C++ based upon how the derived class inherits its features from the base class. These five types are as follows:

  • Single Inheritance

Single Inheritance is the most primitive among all the types of inheritance in C++. In this inheritance, a single class inherits the properties of a base class. All the data members of the base class are accessed by the derived class according to the visibility mode (i.e., private, protected, and public) that is specified during the inheritance.

Single_Inheritance.

Syntax

class base_class_1

{

    // class definition

};

class derived_class: visibility_mode base_class_1

{

    // class definition

};

Description 

A single derived_class inherits a single base_class. The visibility_mode is specified while declaring the derived class to specify the control of base class members within the derived class. 

Example

The following example illustrates Single Inheritance in C++:

#include <iostream>

using namespace std;

// base class 

class electronicDevice

{

public:

    // constructor of the base class 

    electronicDevice()

    {

        cout << "I am an electronic device.\n\n";

    }

};

 // derived class

class Computer: public electronicDevice

{

public:

    // constructor of the derived class

    Computer()

    {

        cout << "I am a computer.\n\n";

    }

};

int main()

{

    // create object of the derived class

    Computer obj; // constructor of base class and

                  // derived class will be called

    return 0;

}

types_of_inheritance_in_cpp_4

In the above example, the subclass Computer inherits the base class electronicDevice in a public mode. So, all the public and protected member functions and data members of the class electronicDevice are directly accessible to the class Computer. Since there is a single derived class inheriting a single base class, this is Single Inheritance.

  • Multiple Inheritance

The inheritance in which a class can inherit or derive the characteristics of multiple classes, or a derived class can have over one base class, is known as Multiple Inheritance. It specifies access specifiers separately for all the base classes at the time of inheritance. The derived class can derive the joint features of all these classes and the data members of all the base classes are accessed by the derived or child class according to the access specifiers. 

/MultipleInheritance

Syntax

class base_class_1

{

    // class definition

}; 

class base_class_2

{

    // class definition

};

class derived_class: visibility_mode_1 base_class_1, visibility_mode_2 base_class_2

{

    // class definition

};

Description

The derived_class inherits the characteristics of two base classes, base_class_1  and base_class_2. The visibility_mode is specified for each base class while declaring a derived class. These modes can be different for every base class.

Example

The following example illustrates Multiple Inheritance in C++:

#include <iostream>

using namespace std;

// class_A

class electronicDevice

{

    public:

        // constructor of the base class 1

        electronicDevice()

        {

            cout << "I am an electronic device.\n\n";

        }

}; 

// class_B 

class Computer

{

    public:

        // constructor of the base class 2

        Computer()

        {

            cout << "I am a computer.\n\n";

        }

}; 

// class_C inheriting class_A and class_B

class Linux_based : public electronicDevice, public Computer

{}; 

int main()

{

    // create object of the derived class

       Linux_based obj; // constructor of base class A, 

                        // base class B and derived class 

                        // will be called

    return 0;

}

types_of_inheritance_in_cpp_5  

In the above example, there are separate base classes, electronicDevice, and Computer. The derived class Linux_based inherits both of these classes forming a Multiple Inheritance structure. The derived class Linux_based has inherited the attributes of both base classes in public mode. When you create an object of the derived class, it calls the constructor of both the base classes. 

  • Multilevel Inheritance

The inheritance in which a class can be derived from another derived class is known as Multilevel Inheritance. Suppose there are three classes A, B, and C. A is the base class that derives from class B. So, B is the derived class of A. Now, C is the class that is derived from class B. This makes class B, the base class for class C but is the derived class of class A. This scenario is known as the Multilevel Inheritance. The data members of each respective base class are accessed by their respective derived classes according to the specified visibility modes.

MultilevelInheritance.

Syntax

class class_A

{

    // class definition

};

class class_B: visibility_mode class_A

{

    // class definition

};

class class_C: visibility_mode class_B

{

    // class definition

};

Description 

The class_A is inherited by the sub-class class_B. The class_B is inherited by the subclass class_C. A subclass inherits a single class in each succeeding level. 

Example

The following example illustrates Multilevel Inheritance in C++:

#include <iostream>

using namespace std;

// class_A

class electronicDevice

{

    public:

        // constructor of the base class 1

        electronicDevice()

        {

            cout << "I am an electronic device.\n\n";

        }

};

// class_B inheriting class_A

class Computer: public electronicDevice

{

    public:

        // constructor of the base class 2

        Computer()

        {

            cout << "I am a computer.\n\n";

        }

};

// class_C inheriting class_B

class Linux_based : public Computer

{

    public:

        // constructor of the derived class

        Linux_based()

        {

            cout << "I run on Linux.\n\n";;

        }

};

int main()

{

    // create object of the derived class 

    Linux_based obj; // constructor of base class 1, 

                    // base class 2, derived class will be called

    return 0;

}

types_of_inheritance_in_cpp_6.

In the above example, the base class electronicDevice is inherited by the subclass Computer which is further inherited by the subclass Linux_based. Since one class is inherited by a single class at each level, it is Multilevel Inheritance. The object of the derived class Linux_based can access the members of the class electronicDevice and Computer directly.

  • Hierarchical Inheritance

The inheritance in which a single base class inherits multiple derived classes is known as the Hierarchical Inheritance. This inheritance has a tree-like structure since every class acts as a base class for one or more child classes. The visibility mode for each derived class is specified separately during the inheritance and it accesses the data members accordingly.

HierarchicalInheritance

Syntax

class class_A

{

    // class definition

};

class class_B: visibility_mode class_A

{

    // class definition

};

class class_C : visibility_mode class_A

{

    // class definition

};

class class_D: visibility_mode class_B

{

    // class definition

};

class class_E: visibility_mode class_C

{

    // class definition

}; 

Description

The subclasses class_B and class_C inherit the attributes of the base class class_A. Further, these two subclasses are inherited by other subclasses class_D and class_E respectively.

Example

The following example illustrates Hierarchical Inheritance in C++:

#include <iostream>

using namespace std;

// base class

class electronicDevice

{

public:

    // constructor of the base class 1

    electronicDevice()

    {

        cout << "I am an electronic device.\n\n";

    }

};

// derived class inheriting base class

class Computer: public electronicDevice

{}; 

// derived class inheriting base class

class Linux_based : public electronicDevice

{}; 

int main()

{

    // create object of the derived classes 

    Computer obj1;     // constructor of base class will be called

    Linux_based obj2;  // constructor of base class will be called 

    return 0;

}

types_of_inheritance_in_cpp_7

In the above example, the base class electronicDevice is inherited by two subclasses Computer and Linux_based. The class structure represents Hierarchical Inheritance. Both the derived classes can access the public members of the base class electronicDevice. When it creates objects of these two derived classes, it calls the constructor of the base class for both objects. 

  • Hybrid Inheritance

Hybrid Inheritance, as the name suggests, is the combination of two or over two types of inheritances. For example, the classes in a program are in such an arrangement that they show both single inheritance and hierarchical inheritance at the same time. Such an arrangement is known as the Hybrid Inheritance. This is arguably the most complex inheritance among all the types of inheritance in C++. The data members of the base class will be accessed according to the specified visibility mode.

HybridInheritance.

Syntax

class class_A

{

    // class definition

};

class class_B

{

    // class definition

};

class class_C: visibility_mode class_A, visibility_mode class_B

{

    // class definition

};

class class_D: visibility_mode class_C

{

    // class definition

};

class class_E: visibility_mode class_C

{

    // class definition

};

Description

The derived class class_C inherits two base classes that are, class_A and class_B. This is the structure of Multiple Inheritance. And two subclasses class_D and class_E, further inherit class_C. This is the structure of Hierarchical Inheritance. The overall structure of Hybrid Inheritance includes more than one type of inheritance.

Example

The following example illustrates the Hybrid Inheritance in C++:

#include <iostream>

using namespace std;

// base class 1

class electronicDevice

{

public:

    // constructor of the base class 1

    electronicDevice()

    {

        cout << "I am an electronic device.\n\n";

    }

};

// base class 2

class Computer

{

public:

    // constructor of the base class 2

    Computer()

    {

        cout << "I am a computer.\n\n";

    }

};

// derived class 1 inheriting base class 1 and base class 2

class Linux_based : public electronicDevice, public Computer

{};

// derived class 2 inheriting derived class 1

class Debian: public Linux_based

{}; 

int

main()

{

    // create an object of the derived class

    Debian obj; // constructor of base classes and

                // derived class will be called 

    return 0;

}

types_of_inheritance_in_cpp_8

In the above example, the three classes electronicDevice, Computer, and Linux_based form the structure of Multiple Inheritance. And the class Debian inherits the class Linux_base forming the structure of Single Inheritance. When an object of the derived class Debian is created, the constructors of all its superclasses are called.

Full Stack Web Developer Course

To become an expert in MEAN StackView Course
Full Stack Web Developer Course

Diamond Problem

The diamond problem in inheritance happens when there is a derived class inheriting the attributes of 2 superclasses, and these superclasses have a common base class. The following diagram represents the structure of a  diamond problem.

Diamondproblem

In a diamond problem, when the two classes class_1 and class_2 inherit the same base class, it creates two copies of the Base_class. So when an object of the derived_class accesses a member of the base class, it causes ambiguity. This ambiguous situation is caused because it is unclear which copy of the base_class member needs to be accessed. And in such a situation the compiler throws an error.

The following example illustrates the ambiguous situation caused by a diamond structured inheritance.

#include <iostream>

using namespace std;

// base class

class Base_class

{

public:

    int x;   

}; 

// class 1

class class_1 : public Base_class

{

public:

    int y;

}; 

// class 2

class class_2 : public Base_class

{

public:

    int z;

}; 

// derived class 3

class derived_class : public class_1, public class_2

{

public:

    int sum;

};

int main()

{

    // create an object of the derived_class

    derived_class obj;

    obj.x = 10;  // ambiguous

    obj.y = 20;

    obj.z = 30;

    obj.sum = obj.x + obj.y + obj.z;

    cout << "The sum is: " << obj.sum << "\n\n";

    return 0;

}

types_of_inheritance_in_cpp_9. 

In the above example, it throws an error because of the ambiguity caused. This happens because there are two copies of the data member “x” of the base_class, one for class_1 and one for class_2. When the object “obj” of the derived_class tries to access this member variable, it is not specified which copy of the variable “x” is to be used. 

There are two ways to avoid the ambiguous situation in a diamond problem.

  1. Using the scope resolution operator.
  2. Using virtual base class keyword.

The following example illustrates the working of the scope resolution operator to remove ambiguity in the diamond problem.

#include <iostream>

using namespace std;

// base class

class Base_class

{

public:

    int x;    

}; 

// class 1

class class_1 : public Base_class

{

public:

    int y;

}; 

// class 2

class class_2 : public Base_class

{

public:

    int z;

};

// derived class 3

class derived_class : public class_1, public class_2

{

public:

    int sum;

}; 

int main()

{

    // create an object of the derived_class

    derived_class obj;

    obj.class_1::x = 10;  // it is now unambiguous

    obj.y = 20;

    obj.z = 30;

    obj.sum = obj.class_1::x + obj.y + obj.z;

    cout << "The sum is: " << obj.sum << "\n\n";

    return 0;

}

types_of_inheritance_in_cpp_10.  

In the above example, the following expression uses the scope resolution operator to specify which copy of “x” is to be used. 

obj.class_1::x;

Here, the class_1’s version of “x” is accessed. In this case, no error is thrown as the ambiguous statement has been resolved to become unambiguous. 

Although the scope resolution operator removes the ambiguity and produces correct output, there are still two copies of the base class. If you require only one copy of the base class, then there is the virtual keyword for this. The virtual keyword allows only one copy of the base class to be created, and the object of the derived class can access the members of the base class in the usual way.

The following example illustrates the working of the virtual keyword to remove ambiguity in the diamond problem.

#include <iostream>

using namespace std;

// base class

class Base_class

{

public:

    int x;   

};

// class 1

class class_1 : virtual public Base_class

{

public:

    int y;

}; 

// class 2

class class_2 : virtual public Base_class

{

public:

    int z;

}; 

// derived class 3

class derived_class : public class_1, public class_2

{

public:

    int sum;

}; 

int main()

{

    // create an object of the derived_class

    derived_class obj; 

    obj.x = 10;  // it is now unambiguous

    obj.y = 20;

    obj.z = 30;

    obj.sum = obj.x + obj.y + obj.z;

    cout << "The sum is: " << obj.sum << "\n\n";

    return 0; 

}

types_of_inheritance_in_cpp_11 

In the above example, two classes class_1 and class_2 inherit the base class as virtual. Any Multiple Inheritance involving these subclasses creates only a single copy of the base_class.  So, now the derived_class has only one copy of the base_class, which makes the following statement valid and unambiguous.

obj.x = 10;

How to Make a Private Member Inheritable?

In inheritance, the private members of a base class are not inherited by the derived classes. So these members of the base class are not accessible to the objects of the derived class. Only the public and the protected members are inherited and can be accessed by the derived classes.

The private members of the base class can be made inheritable in two ways:

  • Modifying the Visibility Mode From Private to Public.

Making the access modifier of the private member public makes it inheritable by the derived classes. However, a problem arises with this approach. The data hiding property is no longer there for that member as it is now accessible to all other functions of the program. 

  • Modifying the Visibility Mode From Private to Protected.

This approach retains the data hiding property of the private member. Modifying the access specifier of a private member as protected, makes it inheritable and accessible by the derived class. If these members are required to be inheritable further beyond the immediately derived class, then they should be inherited as public. Otherwise, they should be inherited as private which will end the inheritance hierarchy beyond the immediately derived class.

Advance your career as a MEAN stack developer with the Full Stack Web Developer - MEAN Stack Master's Program. Enroll now!

Final Thoughts!

In this comprehensive guide on the types of inheritance in C++, you started with a brief introduction to C++ and the concept of parent and child classes. You understood why and when to use which types of inheritance in C++ along with the different visibility modes that can be used with the classes and members.

You understood the five different types of inheritance, their use-cases, examples, and the fundamental differences between them. You looked at a very common problem that arises due to multiple inheritances called the diamond problem and the solution to it. Finally, you saw how to make a private member inheritable.

If you want to learn more about such concepts of C++ with examples, you can check out our guide on C++ for beginners

If you want to land your foot in Full Stack Web Development, you should check out Simplilearn’s comprehensive training program on Full Stack Web Development. This program will help you to learn top technical skills like DevOps, Agile, HTML, CSS, Servlets, JS, Java, and its libraries such as Spring, Hibernate, JPA, etc. This course is led by top industry experts and they are available throughout the course to help you solve your queries. 

You can also check out our complete list of free online courses

If you have any queries related to our article on “Types of inheritance in C++” or any other suggestion, please feel free to drop a comment on the comment box. Our experts will get back to you as soon as possible.

Happy Learning!

About the Author

SimplilearnSimplilearn

Simplilearn is one of the world’s leading providers of online training for Digital Marketing, Cloud Computing, Project Management, Data Science, IT, Software Development, and many other emerging technologies.

View More
  • Disclaimer
  • PMP, PMI, PMBOK, CAPM, PgMP, PfMP, ACP, PBA, RMP, SP, and OPM3 are registered marks of the Project Management Institute, Inc.