Inheritance In C++ With Example Programs

Inheritance in c++

In this blog post tutorial, you will learn about Inheritance in C++ with the help of programming examples. I will describe each small point related to Inheritance because Inheritance is one of the key features of object-oriented programming. This blog post on Inheritance will be helpful for both beginners and experienced. So let’s start this blog post with a question “What is Inheritance in C++”?

 

What is Inheritance in C++?

Inheritance is one of the key features of OOP (Object-oriented programming). It allows us to create a new class (derived or child class) from an existing class (base or parent class). The class whose members are inherited is called the base or parent class, and the class that inherits those members is called the derived or child class.

The child class inherits the characteristics and behaviors from the parent class and can have additional features of its own. In another word you can say that inheritance enables you to create new classes that reuse, extend, and modify the behavior defined in other classes.

For example, imagine we’re writing a survey program for animals, including Cows, Dogs, and Cats. We could write one class for representing cows and two unrelated classes representing dogs and cats, but we’d have to duplicate the functionality that all animals have in common. Instead, C++ allows us to specify the common code in an Animal class, and then specify that the Cow, Dog, and Cat classes share this code.

//Animal is base class

class Animal
{
public:
    int speedCalculator(unsigned int speedOffset);
    int priceCalculator(unsigned int priceOffset);
    int dietCalculator(unsigned int dietOffset);
};

 

Now we want to specify that Cow will inherit the Animal code, but with some additions. This is accomplished in the below code:

//Cow class is child class of the Animalclass

class Cow : public Animal
{
public:
    void milkQuality();

};

Now class Cow has all the data members and methods of Animal, as well as a milkQuality() method. Class Cow inherits from class Animal. This is equivalent to saying that Cow is a derived class, while Animal is its base class. You can also say that Animal is a superclass of Cow or Cow is a superclass of Animal.

I believe you have noticed the use of the keyword public while inheriting Cow from Animal.

class Cow : public Animal

You can also use the keywords private and protected instead of public. In the below section of this tutorial, you will learn the differences between private, public, and protected at the time of inheritance.

 

Similarly, we could make a Dog and Cat class that inherits from Animal and shares its code. This would give a class hierarchy like the following:

Inheritance in cpp

 

Note: Class hierarchies are generally drawn with arrows pointing from derived classes to base classes.

 

is-a relationship:

Inheritance allows us to define “is-a” relationships, but it should not be used to implement “has-a” relationships. So you should use inheritance only if an is-a relationship is present between the two classes.

Few examples of “is a” relationship:

  • Cow is a Animal.
  • Mango is a fruit.
  • Car is a vehicle.
  • Kalakand is a sweet.

Note: It would be a design error to inherit a class A from class B that does not have “is a” relationship.

 

Example: Simple Example of C++ Inheritance:

#include <iostream>
using namespace std;



//Animal is base class
class Animal
{
public:

    //Calculate speed in Km
    int speedCalculator(unsigned int speedOffset)
    {
        const int animalSpeed = (speedOffset < 15)? (speedOffset *10):-1;
        return (animalSpeed);
    }

    //Calculate Price in thousand INR
    int priceCalculator(unsigned int priceOffset)
    {
        const int animalPrice = (priceOffset < 100)? (priceOffset *1000):-1;
        return (animalPrice);
    }

    //Calculate Diet in calories
    int dietCalculator(unsigned int dietOffset)
    {
        const int animalDiet = (dietOffset < 20)? (dietOffset *1000):-1;
        return (animalDiet);
    }
};


// derived class
class Cow : public Animal
{

public:
    void milkQuality()
    {
        cout << "Cow Milk quality is good" << endl;
    }
};

// derived class
class Dog : public Animal
{

public:
    void bark()
    {
        cout << "I can bark! Bho Bho!!" << endl;
    }
};

// derived class
class Cat : public Animal
{

public:
    void climbing()
    {
        cout << "Wow! Cat can climbing on tree" << endl;
    }
};

int main()
{
    // Create object of the Cow class
    Cow cow;
    // Calling members of the base class
    cout<<"Cow speed is = "<<cow.speedCalculator(1)<<endl;
    // Calling member of the derived class
    cow.milkQuality();
    cout<<endl;



    // Create object of the Dog class
    Dog dog;
    // Calling members of the base class
    cout<<"Dog speed is = "<<dog.speedCalculator(5)<<endl;
    // Calling member of the derived class
    dog.bark();
    cout<<endl;

    // Create object of the Cat class
    Cat cat;
    // Calling members of the base class
    cout<<"Cat speed is = "<<cat.speedCalculator(3)<<endl;
    // Calling member of the derived class
    cat.climbing();
    cout<<endl;

    return 0;
}

Output:

Cow speed is = 10
Cow Milk quality is good

Dog speed is = 50
I can bark! Bho Bho!!

Cat speed is = 30
Wow! Cat can climbing on tree

Here, cow (the object of derived class Cow) can access members of the base class Animal. It’s because Cow is inherited from Animal. Similarly, objects dog and cat also access the members of the base class Animal because they are also inherited from the Animal class.

 

Now I believe you are able to understand that why the inheritance is required. In another article, we will discuss the difference between composition and inheritance. Because this day inheritance seems not to be recommended as good practice in programming. Some modern programming languages like Go don’t even allow the use of inheritance but only the alternative, composition.

 

Constructing derived/base class:

When we construct a derived class object, the base class object must be created first. The constructors of base class subobjects are called by the constructor of the derived class. Also, arguments may be provided to those constructors in the member initializer list if required.

A derived-class constructor is always called a base-class constructor. If we do not specify any base-constructor, it calls a default base-constructor. This is because the base-constructor does initialization of derived objects the inherited base-class member. The members of the derived object are initialized by the derived constructor. For example,

#include <iostream>
using namespace std;

class A
{
public:
    A(int n) : data1(n)
    {
        cout << "A() -> ";
        cout <<"data1 = "<<data1<<endl;
    }

protected:
    int data1;
};



class B : public A
{
public:
    B(int n) : A(n),data2(n)
    {
        cout << "B() -> ";
        cout <<"data2 = "<<data2<<endl;
    }

private:
    int data2;
};

int main()
{
    B obj(2);

    return 0;
}

Output:

A() -> data1 = 2
B() -> data2 = 2

 

You can see from the result, the base class constructor is called first then the derived class constructor is called. Actually, the base-class object should be constructed before the code enters the body of the derived-class constructor.

If a class is derived from multiple base classes, the base class constructors are invoked in the order in which they are listed in the declaration of the derived class. For Example,

#include <iostream>
using namespace std;

class A
{
public:
    A()
    {
        cout << "A()\n";
    }
};


class B
{
public:
    B()
    {
        cout << "B()\n";
    }
};
class C
{
public:
    C()
    {
        cout << "C()\n";
    }
};


class DerivedClass : public A, public B,public C
{
public:
    DerivedClass()
    {
        cout << "DerivedClass()\n";
    }
};


int main()
{
    //derived class object
    DerivedClass obj;

    return 0;
}

Output:

A()
B()
C()
DerivedClass()

 

 

C++ access specifiers:

C++ supports three access specifiers public, protected, and private.  An access specifier specifies the access rules for members following it until the end of the class or until another access specifier is encountered. For example,

class X
{
    int a; // X::a is private by default: class used
public:
    int b; // X::b is public
    int c; // X::c is public
};

 

Note:  Any number of access specifiers is allowed and no particular order is required. For example,

struct S
{
    int a; // S::a is public by default: struct used
    
protected:
    int b; // S::b is protected
    
private:
    int c; // S::c is private
    
public:
    int d; // S::d is public
    
};

 

 

So let’s understand all three access specifiers (public, protected, and private) one by one with examples.

private: A member (either data member or member function) declared in a private section of a class can only be accessed by member functions and friends of that class.

class Test
{
private:
    // Access only by member functions 
    //and friends of that class
    int data;
};

 

protected: A member (either data member or member function) declared in a protected section of a class can only be accessed by member functions and friends of that class, and by member functions and friends of derived classes.

class Test
{
protected:
    //Access by member functions and friends of that class,
    //and by member functions and friends of derived classes.
    int data;
};

 

public: A member (either data member or member function) declared in a public section of a class can be accessed by anyone.

class Test
{
public:
    //Access by anyone
    int data;
};

 

 

C++ protected and private Members:

Now I believe that you have a basic idea about the access modifiers. So I am going to explain a very interesting thing which would definitely come to your mind. For example, can a derive class access the private or protected member of the base class? Because, until now I have only explained the member attributes and methods which are public in the base class. So let’s understand this topic one by one.

Protected members:

Protected members of the base class can be accessed by the derived class member functions and friends. We need protected members if we want to hide the data of a class, but still want that data to be inherited by its derived classes. Let’s see an example.

#include <iostream>
using namespace std;


//A is base class
class A
{

protected:
    void displayMsg()
    {
        cout << "I am protected function";
    }

};

//B derived class
class B : public A
{
public:
    void msg()
    {
        displayMsg();
    }
};

int main()
{
    //Derived class object
    B obj;

    //Calling msg function
    obj.msg();

    return 0;
}

Output:

I am protected function

 

Private members:

Private members of the base class can not be accessed by the derived class members. Consider the below example.

#include <iostream>
using namespace std;


//A is base class
class A
{

private:
    void displayMsg()
    {
        cout << "I am protected function";
    }

};

//B derived class
class B : public A
{
public:
    void msg()
    {
        displayMsg();
    }
};

int main()
{
    //Derived class object
    B obj;

    //Calling msg function
    obj.msg();

    return 0;
}

Output:

Inheritance private member

 

 

Accessibility of base classes and base class members (Access Modes in C++ Inheritance):

In the above parts of the article, we have learned about access specifiers. Also, we learned that derived classes can only access the non-private members of the base class.

So far, we have used the public access specifier in order to inherit a class from an existing base class. But we can also use the protected and private access specifiers in place of the public keyword. Let’s understand the effect of access specifiers during the inheritance.

public:If a class is declared to be a base class for another class using the public access specifier, the public members of the base class are accessible as public members of the derived class, and protected members of the base class are accessible as protected members of the derived class.

class A
{

};


class B : public A
{
    /*
    Base class Public member -> Become Public Member of derive class

    Base class Protected member -> Become Protected Member of derive class
    */
};

 

protected:If a class is declared to be a base class for another class using the protected access specifier, the public and protected members of the base class are accessible as protected members of the derived class.

class A
{

};


class B : public A
{
    /*
    Base class Public member -> Become Protected Member of derive class

    Base class Protected member -> Become Protected Member of derive class
    */
};

 

private:  If a class is declared to be a base class for another class using the private access specifier, the public and protected members of the base class are accessible as private members of the derived class.

class A
{

};


class B : public A
{
    /*
    Base class Public member -> Become private Member of derive class

    Base class Protected member -> Become private Member of derive class
    */
};

 

The below table summarizes the above three access modes and shows the access specifier of the members of the base class in the subclass when derived in public, protected, and private modes:

www.aticleworld.com

 

Some important points related to the inheritance which should you remember:

 

1. In the absence of an access specifier for a base class, the public is assumed when the derived class is defined with the class-key struct, and private is assumed when the class is defined with the class-key class. For example,

struct D1 : B
{
    /* ... */
}; // B public by default




class D2 : B
{
    /* ... */
}; // B private by default

 

2. A member of a private base class can be inaccessible as inherited, but accessible directly. See the below example,

//Base class
class A
{
public:
    int data; //non-static member
};


//derived from A
class B : private A
{
};

//derived from C
class C : public B
{
public:
    void funMethod()
    {
        data = 3; // error: data is private in B

        ::A obj; //Ok Create object of A

        obj.data = 3; // OK ( obj.data is different from this->data)

        ::A* bp1 = this; // error: A is a private base class

        ::A* bp2 = (::A*)this; // OK with cast

        bp2->data = 3; // OK: access through a pointer to A.
    }
};

 

3. Constructors of a base class can be explicitly inherited. We can inherit the base class constructor through “using declarations”. If the using-declarator names a constructor, it declares that the class inherits the named set of constructor declarations from the nominated base class. For example,

#include <iostream>
using namespace std;

struct A
{
    A(int data) { }
};


struct D: A
{
    using A::A;  // inherits A(int)
    int x;
    void test();
};


void D::test()
{
    D d(2); // OK: D is initialized by calling A(2)
}

int main()
{

    return 0;
}

 

4. Friendship is not inherited. You can understand this like your friend’s children are not your friends. For example,

#include <iostream>
using namespace std;

class A
{
private:
    int a;
    friend void f();
};

class B : public A
{
    int data;
};

void f()
{
    A obj1;

    obj1.a = 10; // Ok

    B obj2;

    obj2.data = 10; //Error
}

int main()
{
    f();
    return 0;
}

Friend of A is not also a friend of B. Having Binherited from Avia public access means that all public and protected members of A are accessible as members of B. Attribute “data” is a private member of B. Since f() is not a friend of B, it cannot access private members of B.

 

5. Base class members can be referred to in expressions in the same manner as other members of the derived class unless their names are hidden or ambiguous. For example,

#include <iostream>
using namespace std;

class A
{
public:
    int a;
};

class B : public A
{
public:
    int b;
};



int main()
{
    B obj; //derived class object

    /*
    Base class member referred to
    the same manner as derived class.
    */
    obj.a = 10; //Base class member

    obj.b = 20; //Derived class member

    return 0;
}

 

The scope resolution operator :: can be used to refer to a direct or indirect base member explicitly, even if it is hidden in the derived class.

#include <iostream>
using namespace std;

class A
{
public:
    int a;
};

class B : public A
{
public:
    int a;
    void fun()
    {
        A::a = 10;
        B::a = 10;
        cout << "A's a is " << A::a<<endl;
        cout << "B's a is " << B::a;
    }
};


int main()
{
    B obj; //derived class object

    obj.fun(); //Calling fun()

    return 0;
}

 

6. A derived class can itself serve as a base class subject to access control. A pointer to a derived class can be implicitly converted to a pointer to an accessible unambiguous base class. For example,

#include <iostream>
using namespace std;


//Base class
class BaseClass
{
public:
    int data;
};


//child class
class DerivedClass  : public BaseClass
{

};

int main()
{
    //derived class ptr
    DerivedClass * derivePtr = new DerivedClass ;

    // upcast - implicit type cast allowed
    BaseClass* basePtr = derivePtr;

    basePtr->data = 27;

    cout<<"basePtr->data = "<<basePtr->data <<endl;

    delete basePtr;

    return 0;
}

Output:

basePtr->data = 27

 

7.Using the final keyword (C++11) you can protect the class from inheritance. If a class or struct is marked as final then it becomes non-inheritable and cannot be used as a base class/struct.

#include <iostream>

//class with final keyword
class A final
{
};

class B : public A
{
};

int main()
{
    B obj;

    return 0;
}

Output:

error: cannot derive from ‘final’ base ‘A’ in derived type ‘B’

 

8.  Sometimes you don’t want to allow the derived class to override the base class’ virtual function. Using the final the keyword you can prevent the overriding of the virtual function of the base class.

#include <iostream>
using namespace std;


//Base class
class Base
{
public:
    //virtual fun with final keyword
    virtual void fun() final
    {
        cout << "fun() in Base";
    }
};


//Derived class
class Derived : public Base
{
    //Try to override the virtual function
    // of the base class
    void fun()
    {
        cout << "fun() in Derived\n";
    }
};



int main()
{
    //object of derived class
    Derived obj1;

    /* Assigning derived class object
       to base class reference.
    */
    Base &obj2 = obj1;

    //calling fun of derive class
    obj2.fun();

    return 0;
}

Output:

error: overriding final function ‘virtual void Base::fun()

 

 

Types of inheritance in C++

I will cover this topic in a separate blog post. Here I am only describing the few basic types of inheritance supported by C++ with images and example code.

Single Inheritance in C++

This is a basic type of inheritance in which only one derived class is inherited from one base class. In the below example, class B is derived from class A.

www.aticleworld.com
//base class
class A
{
  
}

//child class
class B : public A
{
  
}

 

Multiple Inheritance in C++

In which one class is derived from more than two classes. In the below example class C is derived from class A and class B.

www.aticleworld.com
// first base class
class A
{
  
}

//Second base class
class B 
{
  
}

//class derived from A and B
class C : public A public B
{
  
}




Hierarchal Inheritance in C++

In which more than one class is derived from the same base class. In the below example, class B and class C are derived from the same base class A.

www.aticleworld.com
//Base class
class A
{
  
}

//derived class B from A
class B : public A
{
  
}

//derived class C from A
class C : public A
{
  
}

 

Multilevel Inheritance in C++

In which derived class is derived from another derived class. In the below example class C is derived from another derived class B.

www.aticleworld.com
//Base class
class A
{
  
}

//child class of A
class B :  public A
{
  
}

//Child class of B
class C : public B
{
  
}

 

Hybrid Inheritance in C++

Hybrid inheritance is the composition of more than one inheritance. The below example is the composition of multilevel and hierarchal inheritance.

www.aticleworld.com
//Parent class
class A
{
  
}

//B is child class of A
class B :  public A
{
  
}

//C is child class of A
class C : public A
{
  
}

//D is child class of B nd C
class D : public B, public C
{
  
}

 




Advantage of Inheritance in C++

I have already discussed at the beginning of the article, inheritance minimizes the development cycle of the product to avoid duplicate code in the project. It also arranges the code in a better way which increases the readability of the code and provides the flexibility to the user to make any changes easily.

In below, I am describing some beneficial features of inheritance in c++.

  • Reusability: It provides the facility to the derived class to use the public method of the base class without rewriting the methods.
  • Overriding: It is a very useful feature of objective-oriented programming. Without the help of inheritance, we cannot use this property.
  • Extensibility: It is another advantage of inheritance. It extends the base class logic as per the business logic of the derived class.
  • Data hiding: It is also a good feature of the inheritance which provides the facility to the base class to decide which data to keep private that child class would not be able to change.

 

Disadvantages of Inheritance in C++

  • In Inheritance, both base class and child classes are tightly coupled to each other. Hence If you change anything in the code of the base class, it will get effects all the child classes.
  • In a class hierarchy, many data members remain unused and the memory allocated to them is not utilized. Hence affect the performance of your program if you have not implemented inheritance correctly.

 

Recommended Articles for you:

Leave a Reply

Your email address will not be published. Required fields are marked *