Inheritance is a mechanism of reusing and extending existing classes without modifying them, thus producing hierarchical relationships between them.
Inheritance is almost like embedding an object into a class. Suppose that you declare an object x of class A in the class definition of B. As a result, class B will have access to all the public data members and member functions of class A. However, in class B, you have to access the data members and member functions of class A through object x. The following example demonstrates this:
#include <iostream>
using namespace std;
class A {
int data;
public:
void f(int arg) { data = arg; }
int g() { return data; }
};
class B {
public:
A x;
};
int main() {
B obj;
obj.x.f(20);
cout << obj.x.g() << endl;
// cout << obj.g() << endl;
}
In the main function, object obj accesses function A::f() through its data member B::x with the statement obj.x.f(20). Object obj accesses A::g() in a similar manner with the statement obj.x.g(). The compiler would not allow the statement obj.g() because g() is a member function of class A, not class B.
The inheritance mechanism lets you use a statement like obj.g() in the above example. In order for that statement to be legal, g() must be a member function of class B.
Inheritance lets you include the names and definitions of another class's members as part of a new class. The class whose members you want to include in your new class is called a base class. Your new class is derived from the base class. The new class contains a subobject of the type of the base class. The following example is the same as the previous example except it uses the inheritance mechanism to give class B access to the members of class A:
#include <iostream>
using namespace std;
class A {
int data;
public:
void f(int arg) { data = arg; }
int g() { return data; }
};
class B : public A { };
int main() {
B obj;
obj.f(20);
cout << obj.g() << endl;
}
Class A is a base class of class B. The names and definitions of the members of class A are included in the definition of class B; class B inherits the members of class A. Class B is derived from class A. Class B contains a subobject of type A.
You can also add new data members and member functions to the derived class. You can modify the implementation of existing member functions or data by overriding base class member functions or data in the newly derived class.
You may derive classes from other derived classes, thereby creating another level of inheritance. The following example demonstrates this:
struct A { };
struct B : A { };
struct C : B { };
Class B is a derived class of A, but is also a base class of C. The number of levels of inheritance is only limited by resources.
Multiple inheritance allows you to create a derived class that inherits properties from more than one base class. Because a derived class inherits members from all its base classes, ambiguities can result. For example, if two base classes have a member with the same name, the derived class cannot implicitly differentiate between the two members. Note that, when you are using multiple inheritance, the access to names of base classes may be ambiguous. See Multiple inheritance (C++ only) for more detailed information.
A direct base class is a base class that appears directly as a base specifier in the declaration of its derived class.
An indirect base class is a base class that does not appear directly in the declaration of the derived class but is available to the derived class through one of its base classes. For a given class, all base classes that are not direct base classes are indirect base classes. The following example demonstrates direct and indirect base classes:
class A {
public:
int x;
};
class B : public A {
public:
int y;
};
class C : public B { };
Class B is a direct base class of C. Class A is a direct base class of B. Class A is an indirect base class of C. (Class C has x and y as its data members.)
Polymorphic functions are functions that can be applied to objects of more than one type. In C++, polymorphic functions are implemented in two ways: