Derivation (C++ only)

Inheritance is implemented in C++ through the mechanism of derivation. Derivation allows you to derive a class, called a derived class, from another class, called a base class.

Read syntax diagramSkip visual syntax diagramDerived class syntax
 
>>-derived_class--:--------------------------------------------->
 
   .-,---------------------------------------------------------.
   V                                                           |
>----+----------------------------+--qualified_class_specifier-+-><
     +-virtual--+-----------+-----+
     |          +-public----+     |
     |          +-private---+     |
     |          '-protected-'     |
     '-+-public----+--+---------+-'
       +-private---+  '-virtual-'
       '-protected-'
 

In the declaration of a derived class, you list the base classes of the derived class. The derived class inherits its members from these base classes.

The qualified_class_specifier must be a class that has been previously declared in a class declaration.

An access specifier is one of public, private, or protected.

The virtual keyword can be used to declare virtual base classes.

The following example shows the declaration of the derived class D and the base classes V, B1, and B2. The class B1 is both a base class and a derived class because it is derived from class V and is a base class for D:

class V { /* ... */ };
class B1 : virtual public V { /* ... */ };
class B2 { /* ... */ };
class D : public B1, private B2 { /* ... */ };

Classes that are declared but not defined are not allowed in base lists.

For example:

class X;

// error
class Y: public X { };

The compiler will not allow the declaration of class Y because X has not been defined.

When you derive a class, the derived class inherits class members of the base class. You can refer to inherited members (base class members) as if they were members of the derived class. For example:

class Base {
public:
  int a,b;
};

class Derived : public Base {
public:
  int c;
};

int main() {
  Derived d;
  d.a = 1;    // Base::a
  d.b = 2;    // Base::b
  d.c = 3;    // Derived::c
}

The derived class can also add new class members and redefine existing base class members. In the above example, the two inherited members, a and b, of the derived class d, in addition to the derived class member c, are assigned values. If you redefine base class members in the derived class, you can still refer to the base class members by using the :: (scope resolution) operator. For example:

#include <iostream>
using namespace std;

class Base {
public:
  char* name;
  void display() {
    cout << name << endl;
  }
};

class Derived: public Base {
public:
  char* name;
  void display() {
    cout << name << ", " << Base::name << endl;
   }
};

int main() {
  Derived d;
  d.name = "Derived Class";
  d.Base::name = "Base Class";

  // call Derived::display()
  d.display();

  // call Base::display()
  d.Base::display();
}

The following is the output of the above example:

Derived Class, Base Class
Base Class

You can manipulate a derived class object as if it were a base class object. You can use a pointer or a reference to a derived class object in place of a pointer or reference to its base class. For example, you can pass a pointer or reference to a derived class object D to a function expecting a pointer or reference to the base class of D. You do not need to use an explicit cast to achieve this; a standard conversion is performed. You can implicitly convert a pointer to a derived class to point to an accessible unambiguous base class. You can also implicitly convert a reference to a derived class to a reference to a base class.

The following example demonstrates a standard conversion from a pointer to a derived class to a pointer to a base class:

#include <iostream>
using namespace std;

class Base {
public:
  char* name;
  void display() {
    cout << name << endl;
  }
};

class Derived: public Base {
public:
  char* name;
  void display() {
    cout << name << ", " << Base::name << endl;
   }
};

int main() {
  Derived d;
  d.name = "Derived Class";
  d.Base::name = "Base Class";

  Derived* dptr = &d;

  // standard conversion from Derived* to Base*
  Base* bptr = dptr;

  // call Base::display()
  bptr->display();
}

The following is the output of the above example:

Base Class

The statement Base* bptr = dptr converts a pointer of type Derived to a pointer of type Base.

The reverse case is not allowed. You cannot implicitly convert a pointer or a reference to a base class object to a pointer or reference to a derived class. For example, the compiler will not allow the following code if the classes Base and Class are defined as in the above example:

int main() {
  Base b;
  b.name = "Base class";

  Derived* dptr = &b;
}

The compiler will not allow the statement Derived* dptr = &b because the statement is trying to implicitly convert a pointer of type Base to a pointer of type Derived.

If a member of a derived class and a member of a base class have the same name, the base class member is hidden in the derived class. If a member of a derived class has the same name as a base class, the base class name is hidden in the derived class.

Related information