C++ Inheritance

Inheritance lets a derived class reuse the members of a base class. It models an “is a” relation: a Dog is an Animal.

#include <iostream>
#include <string>

class Animal {
public:
    explicit Animal(std::string n) : name(std::move(n)) {}
    void eat() const { std::cout << name << " is eating\n"; }
protected:
    std::string name;
};

class Dog : public Animal {
public:
    explicit Dog(std::string n) : Animal(std::move(n)) {}       // call the base constructor
    void bark() const { std::cout << name << " says Woof!\n"; }
};

int main() {
    Dog d("Tommy");
    d.eat();
    d.bark();
}
Output

Tommy is eating
Tommy says Woof!

Constructor and destructor order

#include <iostream>

struct A { A() { std::cout << "A "; } ~A() { std::cout << "~A "; } };
struct B : A { B() { std::cout << "B "; } ~B() { std::cout << "~B "; } };
struct C : B { C() { std::cout << "C "; } ~C() { std::cout << "~C "; } };

int main() {
    C c;
    std::cout << '\n';
}
Output

A B C
~C ~B ~A

The constructors run from the base to the derived class. The destructors run in the opposite order.

Public, protected and private inheritance

Almost always use public inheritance. The other two are for special cases (“implemented in terms of”).

Hiding and calling the base version

#include <iostream>

struct Base {
    void hello() const { std::cout << "Base hello\n"; }
};

struct Derived : Base {
    void hello() const {
        Base::hello();                    // call the base version
        std::cout << "Derived hello\n";
    }
};

int main() {
    Derived().hello();
}
Output

Base hello
Derived hello

Multiple inheritance and the diamond

C++ allows a class to inherit from many classes. If two bases share one common base, you get the diamond problem: two copies of the top class. The fix is virtual inheritance.

#include <iostream>

struct Person { int id = 7; };
struct Teacher : virtual Person { };
struct Student : virtual Person { };
struct TeachingAssistant : Teacher, Student { };

int main() {
    TeachingAssistant ta;
    std::cout << ta.id << '\n';            // one shared Person: no ambiguity
}
Output

7

Prefer composition

If the relation is “has a” (a Car has an Engine), put an object inside the class instead of inheriting. It is more flexible.

Note: The next chapter shows virtual functions, which make inheritance really useful. Next: C++ Polymorphism and Virtual Functions.

Congratulations! Chapter Finished. Learn more about the similar topics:
Exercises & Assignments
No Content Found.
Interview Questions & Answers
No Content Found.