Select Page

C++ continues to attract developers thanks in large part to classes and objects that make code more reusable. 

To establish how classes interact with one another in C++, developers can define relationships between classes. One of such relationships is inheritance, and it provides a logically sound way to reuse code between classes.

In this article, we cover the mechanics of inheritance to show you how to write efficient code in C++. 

What Is Inheritance in C++?

Inheritance in an object-oriented programming (OOP) language like C++ defines relationships between classes. A class in C++ is a template or blueprint that allows for the creation of objects. An OOP language then uses these objects as part of a structured approach to programming solutions, including the data and values a C++ developer can easily access.

In an inheritance relationship between objects, you’ll see at least a base and a derived class. You may also see these referred to as child and parent classes. Child or derived classes inherit data and functions from parent or base classes. Creating a child class essentially copies everything the parent class has to offer, albeit providing us with the flexibility to add complexity to the child class later on. 

For example, the class Fruit would be parent to the class Apple:

#include <iostream>
#include <string>
using namespace std;

class Fruit{ // Base or parent class
    public:
      string taste = "sweet";
      void eat(){
          cout << "This fruit is delicious! \n";
          cout << "What kind is it? \n";
      }     
};
 
class Apple: public Fruit{ // Derived or child class
    public:
        string type = "an apple";
};

int main(){
    Apple forEating;
    forEating.eat();
    cout << "It's " + forEating.type + "." + " It tastes really " + forEating.taste + ".";
    
    return 0;
}

Although the final output “taste” is originally declared in Fruit, it’s inherited by Apple and therefore, you can access it by declaring only the child class. The program above gives us the following output:

This fruit is delicious! 
What kind is it? 
It's an apple. It tastes really sweet.

You may have noticed the class members are being defined here as “public.” This simply means other classes can access the data and functions inside the given class. The ability to define a class as public, private or protected gives C++ developers a method of access control. 

Whereas in a public class, functions are accessible within all other classes, that’s not the case for private and protected classes. The functions defined within a private class are only accessible within the same class. In a protected class, on the other hand, access from outside the class is denied but allowed in derived classes.

Let’s visualize the differences:

Level of Access Public Private Protected
Within the class + + +
Outside the class +
In derived classes + +

The Benefits of Inheritance in C++

The main idea behind incorporating inheritance into your object-oriented code is to make it more reusable. Cutting out code duplication allows you to shorten your project’s production time and therefore achieve lower overall cost.

Should you decide that you want to add an attribute or member function to several classes, you’ll no longer need to incorporate them one-by-one — provided each of these classes shares a base class. Once you include the addition at the parent class level, all of the child classes will automatically receive the corresponding attribute or member function.

Another benefit of using inheritance in C++ is its ability to produce more readable code. Using inheritance means that your code repeats itself less because you only define shared functions once, in the parent class. Having only one definition is also handy when you need to modify an attribute or a function for both parent and child classes. You can update the function or the attribute in the parent class, and the changes will automatically take effect for the child classes as well.

After all, readability is important not only from the original programmer’s standpoint, but also from those who may need to work with the code later.

That said, it’s important to note that readability depends on other factors beyond your code’s length and repetitiveness (or lack thereof). In other words, inheritance in C++ is certainly useful from a readability standpoint, but is by no means a magic bullet.

The Disadvantages of Inheritance in C++

When working with inheritance in C++, a key drawback to be aware  of is that your modifications of parent classes could lead to errors or issues in the child classes.

In addition, once the hierarchy between classes grows complex, certain attributes or member functions may end up forgotten and unused. This leads to a waste of memory and possibly a slower product.

One method to combat these issues is to use unified modeling language (UML) diagrams. These diagrams can help you visualize the relationships between the classes, as well as help you keep track of all attributes and member functions.

There are many different kinds of UML diagrams depending on the objective. For our example, an object diagram would show the relationship between the parent and child classes as well as display the attributes they possess.

Different Types of Inheritance

Depending on the structure and complexity of the hierarchy between your classes, inheritance in C++ can come in these forms:

  • Single inheritance
  • Multiple inheritance
  • Hierarchical inheritance
  • Multi-level inheritance
  • Hybrid inheritance

Single inheritance refers to a relationship between exactly two classes: one parent class and one child class. If the only fruit we had available were an apple, here’s how it would look:

class Fruit{ // Base or parent class
    public:
      Fruit(){
          cout << "This fruit is delicious! \n";
      }
};
 
class Apple: public Fruit{ // Derived or child class
    public:
    Apple(){
        cout << "It's an apple.";
    }
};

int main(){
    Apple forEating;
    
    return 0;
}

The output would be:

This fruit is delicious! 
It's an apple.

Now, if you decide that the class Apple should belong to other parent classes like class Healthy, then our single inheritance becomes a multiple inheritance. In a multiple inheritance, a child class has to have at least two parent classes.

class Fruit{ // Base or parent class
    public:
      Fruit(){
          cout << "This fruit is delicious! \n";
      }
};

class Healthy{ // Second parent class
    public:
    Healthy(){
        cout << "It is good for you! \n"
    }
}

class Apple: public Fruit, public Healthy{ // Derived or child class
    public:
    Apple(){
        cout << "It's an apple.";
    }
};

int main(){
    Apple forEating;
    
    return 0;
}

Then, when we add more fruits to our class Fruit, we then have a hierarchical inheritance as we have more than one child class. With hierarchical inheritance, there’s no limit to how many separate child classes Fruit could have:

class Fruit{ // Base or parent class
    public:
      Fruit(){
          cout << "This fruit is delicious! \n";
      }
};

class Apple: public Fruit{ // First child
    public:
    Apple(){
        cout << "It's an apple.";
    }
};

class Banana: public Fruit{ // Second child
    public:
    Banana(){
        cout << "It's a banana.";
    }
};

int main(){
    Apple forEating;
    Banana forMunching;
    return 0;
}

What if you wanted to continue the lineage of your child class? There’s an inheritance type for that, too. It’s called a multi-level inheritance and it refers to when a child class becomes a parent class for its own child class. For example, our class Apple could have a child class called “Granny Smith,” while still being a child class to Fruit.

class Fruit{ // Base or parent class
    public:
      Fruit(){
          cout << "This fruit is delicious! \n";
      }
};

class Apple: public Fruit{ // First child
    public:
    Apple(){
        cout << "It's an apple. \n";
    }
};

class Granny_Smith: public Apple{ // Child of first child
    public:
    Granny_Smith(){
        cout << "I like this type of apples.";
    }
};

int main(){
    Granny_Smith forEating;
    return 0;
}

The final type of inheritance is the hybrid inheritance, that occurs when more than one level of inheritance is present in one set of classes and must be connected by a relationship. 

Continue Your C++ Journey

In this article, we explored the benefits, disadvantages and kinds of inheritance in C++. Understanding classes and the relationships between them is crucial to becoming a developer in an object-oriented programming language.

So what’s the next step?

At Udacity, we offer an expert-led C++ Nanodegree program that prepares you for a career as a C++ developer. 

Enroll in our online C++ Nanodegree program today!