top of page

Inheritance

What is inheritance?


In object oriented programming, inheritance is a mechanism by which a new class can be created as an extension of an existing class. Inheritance helps us in code reuse.

The existing class is called base class/super class  and new class is called derived class/ sub class  or inherited class.

 

Derived class is an extension of base class. It inherits all the members of the base class (even the private members). And it can define new members of its own.

 

Base class members which are public and protected are accessible from derived class object. Private members of base class are not directly accessible in derived class but can be accessed using getters and setters.

Syntax

class derived-class:access-specifier base-class

{

   /* members*/

};

Note : The base class must have been declared earlier.

 

Access-specifier tells the mode of inheriting. It can be one of public, private or protected. public is most commonly used access specifier. If access specifier is omitted, access defaults to private.

Let us look at an example.

In the example above, we have defined a class polygon which is base class. We derive triangle class from polygon class using the header

    

      class triangle:public polygon

 

Now this triangle class has inherited all the members of polygon viz. num_sides, print_area() and setN().

triangle class also has defined its own members base, height and setSides().

 

In the setSides() function accessing private member of base class num_sides will give an error. A private data member of a class can not be accessed even by inherited classes.

 

But trianlge class can use setN() method of base class because it is a  protected function in base class.

     A protected member of a class can be accessed by the same class and its derived classes.

As we have used public mode of inheritance, the public function print_area()  will reaminl public in triangle class. And protected member setN() is also protected in triangle class.

 

t.setN() can not be used in main() because it is a protected member.

The output of the program is

 

    AreaArea

Now the question arises

Which members of base class are inherited by derived class?

 

Derived class inherits all the members of base class except for

  1. Constructors and destructors

  2. Overloaded operators

  3. Friend functions

IS-A

 

Each object of a derived class IS AN object of base class.  


Remember that derived class object is a base class object. So whenever a base class object is needed, you can use a derived class object.

 

But the reverse is not true. A base class object is not a derived class object. A derived class has more attributes.

e.g.

A triangle is a polygon. But a polygon is not a triangle.

The function printPolyArea() has a parameter of type polygon. But we can send a polygon object or a triangle object to it.

As expected, the printPolyArea() function which has a polygon parameter accepts t also as an argument. Because t- a triangle is also a polygon.

Also notice that the statement

       p=t;

is fine. And it compiles. Because a derived class object is a base class object.

But the statement

       t = p;

gives an error because a base class object is not a derived class object.

Object slicing

When an object is upcasted (converted from derived to base class. Called so because of inheritance diagram), it will contain only base class elements and will lose derived class elements.

 

This is called object slicing.

 

In the above example, a triangle class object is upcasted to polygon class object, it will contain base, height and setSides().

Constructors and Destructors of Derived Class


When an object of derived class is created,

  • first constructor of base class is called implicitly.

  • next constructor of derived class is called.

 

If base class does not have default constructor and it can't be called implicitly, a compiler error is generated.

 

Conversely, when derived object is being destroyed,

  • first destructor of derived class is called.

  • then destructor of base class is called.

In main() function when we create t - a triangle class object, first base class constructor - polygon constructor is called. Followed by derived class constructor - triangle constructor.

 

When main function exits, derived class destructor is called (~triangle()) followed by base class destructor (~polygon())

Output of the program is 

   Polygon constructor triangle constructor Area triangle destructor polygon destructor

Member Initializer list for Base class

What happens if the base class does not have a default constructor? What parameters are supplied to the implicit call of base class constructor? Or will there be an error?

 

If base class has no default constructor, then derived class can not call base constructor automatically. There will be a compiler error.

When we compile the program above, we get the following error

err.cpp: In constructor ‘B::B()’:
err.cpp:6:7: error: no matching function for call to ‘A::A()’
class B:public A

 

The program above fails to compile because B constructor for obj1  tries to call A constructor. But it can not call constructor, because A has no default constructor.

To avoid such errors, derived class must define a constructor, which must call base class constructor explicitly using its  member initializer list. And this explicit call must provide the arguments for base class constructor.

Let us correct the previous example.

Here B class constructor is written with initializer list and it calls A class constructor with argument 12.

Function Overriding:
 

Redefining the base class function in a derived class using the same signature is called function over-riding.

Remember in our previous example, polygon class did not give correct value for its area. Instead it just displayed area. Because we do not know what is its area, until more information is provided.  But a triangle class can give the area as 1/2 * base *height.

 

So triangle class can redefine the print_area() function. This is called overriding the base class function.

 

Function overriding is derived class providing its own version of base class function.

 

This overriding function in derived class must have same signature as base class function. 

We have re-written print_area() function for triangle class by calculating area and displaying it. Now triangle object t will call this overriding function and print area as 6. But polygon object p will still call base class function and just display the word area.

Output of the program is

Area Area is 6

Name Hiding

The overriding function must have the same signature as the base class function. What if the signature is different? Will the derived class object be able to use both versions of function?

No. If we define a base class function with different signature in derived class, then base class version will not be usable by derived class objects.

 

This is name hiding.

If we define print_area() function in derived class with one parameter as

        class triangle

     {

             int base,height;

          public:

             triangle(int b,int h);

             void print_area(float area);

      }

 

Now derived class objects can not call 0 parameter print_area() function.

      polygon p(10);

     p.print_area();//ok

     triangle t(6,8);

     t.print_area(12.8);//ok

     t.print_area();//error

 

One hint though. If we really want to call base class function then we can use scope resolution operator.

      

              t.polygon::print_area();

bottom of page