Definition

Inheritance in C++ is the capability of one class to acquire properties and characteristics from another class. The class whose properties are inherited by other class is called the Parent or Base or Super class. The class which inherits properties of other class is called Child or Derived or Sub class. It makes the code reusable.

Different types of Inheritance are

  • Single Inheritance : One derived class inherits from only one base class.
  • Multiple Inheritance : Single derived class may inherit from two or more than two base classes.
  • Hierarchical Inheritance : Multiple derived classes inherits from a single base class.
  • Multilevel Inheritance : Derived class inherits from a class, which in turn inherits from some other class.
  • Hybrid Inheritance : Combination of Hierarchical and Mutilevel Inheritance.

Syntax

Below is the syntax of inhering class.

class SubclassName : accessSpecifier SuperclassName

Super class must be already defined or at-least declared before the subclass declaration. Access specifier is one of public, protected, or private. If the access-specifier is not used, then it is private by default. Access modifier is used to specify, the mode in which the properties of super class will be inherited into subclass. Inheritance can either be private, protected or public.

  • Public Inheritance : Protected member of super class becomes protected members of derived class and public becomes public.
  • Private Inheritance : Public and Protected members of super class become private members of derived class.
  • Protected Inheritance : Public and protected members of Super class becomes protected members of derived class.

Constructor Call Order

Base class constructors are always called in the derived class constructors. Whenever you create derived class object, first the base class constructor is called and then the derived class’s constructor.

class Base
{
public:

  // Default constructor
  Base() {
    std::cout <<__FUNCTION__ << ": Default constructor" << std::endl;
  }

  // Parameterized constructor
  Base(int i)  {
    val1 = i;
    std::cout << __FUNCTION__ << ": Parameterized constructor" << std::endl;
  }

private:
  int val1;
};

class Derived : public Base
{
public:

  // Default constructor
  Derived() {
    std::cout << __FUNCTION__ << ": Default constructor" << std::endl;
  }

  // Parameterized constructor
  // Explicit call to Base class constructor
  Derived(int j) :Base(j)
  {
    val2 = j;
    std::cout << __FUNCTION__ << ": Parameterized constructor" << std::endl;
  }

private:
  int val2;
};

int main()
{
  Derived d1;
  Derived d2(10);
}

// Output
Base::Base: Default constructor
Derived::Derived : Default constructor
Base::Base : Parameterized constructor
Derived::Derived : Parameterized constructor

Example

The data members (variables and functions) possessed by the derived class are specific to the type of class. So two different objects of a class will have same member variables and functions, but may have different information stored in their variables. In the below example Dog class is inheriting Animal class

// Super Class
class Animal
{
public:
  Animal();
  ~Animal();

  void eat() {
    std::cout << "Eat";
  }

  void sleep() {
    std::cout << "Sleep";
  }
  void drink() {
    std::cout << "Drink";
  }

private:
  int legs;
  int arms;
  int age;
};

// Derived Class
class Dog : public Animal
{
public:
  void purr();

private:
  int fur_color;
};

int main()
{
  Dog d;

  // Accessing Super class method
  d.sleep();
}

Multiple Inheritance

Multiple inheritance enables a derived class to inherit members from more than one base class. To use multiple inheritance, specify each base class (just like in single inheritance), separated by a comma. Base class’s constructors are called inside derived class’s constructor, in the same order in which they are inherited.

In the below example class Derived inherit from two class Base1 and Base2.

class Base1
{
public:

  // Default constructor
  Base1() {
    val1 = 0;
    std::cout <<__FUNCTION__ << ": Default constructor" << std::endl;
  }

  // Parameterized constructor
  Base1(int i)  {
    val1 = i;
    std::cout << __FUNCTION__ << ": Parameterized constructor" << std::endl;
  }

private:
  int val1;
};

class Base2
{
public:

  // Default constructor
  Base2() {
    val1 = 0;
    std::cout << __FUNCTION__ << ": Default constructor" << std::endl;
  }

  // Parameterized constructor
  Base2(int i) {
    val1 = i;
    std::cout << __FUNCTION__ << ": Parameterized constructor" << std::endl;
  }

public:
  int val1;
};

class Derived : public Base1, Base2
{
public:

  // Default constructor
  Derived() {
    val2 = 0;
        // To access the attribute in super class, use scope resoltion operator
        std::cout << __FUNCTION__ << ": Default constructor" << Base2::val1 << std::endl;
  }

  // parameterized constructor
  Derived(int j) :Base1(j)
  {
    val2 = j;
    std::cout << __FUNCTION__ << ": Parameterized constructor" << std::endl;
  }

private:
  int val2;
};

int main()
{
  Derived d1;
}

// Output
Base1::Base1: Default constructor
Base2::Base2: Default constructor
Derived::Derived: Default constructor

Reference

Inheritance