Inheritance

Let us try to understand the basics of inheritance with the help of below example.

In this, we have created one class viz. person. This class has some basic information like age and name of a person.

Now, let’s say that I want to create a student class. First option is that all the information we keep in the student class like age, name, roll number and standard. Other option is to keep the basic or common information in one class and use this class to form a student class. Here comes the role of inheritance.

Student class is inherited from person class. So now we don’t have to keep the information like age and name in the student class instead we get it from person class.

Here person class is called base or parent class and student class is called derived or child class.

 

#include <iostream>
#include <cstring>
using namespace std;

class person {
    unsigned int m_age;
    char m_firstName[50];
    char m_lastName[50];
public:
    person(unsigned int age, char* firstName, char* lastName)
    {
        cout << "person Initialization" << endl;
        m_age = age;
        strncpy(m_firstName, firstName, strlen(firstName));
      m_firstName[strlen(firstName)] = '\0';
        strncpy(m_lastName, lastName, strlen(lastName));
       m_lastName[strlen(lastName)] = '\0';

        cout << "Age: " << m_age << endl;
        cout << "firstName: " << firstName << endl;
        cout << "lastName: " << lastName << endl;
    }

    ~person() {
       cout << “person destructor” << endl;
    }

    unsigned int getAge() {
        return m_age;
   }    

char* getFirstName() {
        return m_firstName;
    }

    char* getLastName() {
        return m_lastName;
    }
};

class student: public person {
    unsigned int m_rollNumber;
    unsigned int m_class;
public:
    student(unsigned int rollNumber, unsigned int cls,
            unsigned int age, char* firstName, char* lastName): person(age, firstName, lastName) {
        cout << "student Initialization" << endl;
        m_rollNumber = rollNumber;
        m_class = cls;
        cout << "Roll Number: " << m_rollNumber << endl;
        cout << "Class: " << m_class << endl;
    }

    ~student() {
        cout << “student destructor” << endl;
    }

    unsigned int getRollNumber() {
        return m_rollNumber;
    }

    unsigned int  getClass() {
        return m_class;
    }
};

int main()
{
    char firstName[] = "Vikas";
    char lastName[] = "Gupta";
    student st(21243, 5, 10, firstName, lastName);
    cout << “Name: “ << st.getFirstName() << “ “ << st.getLastName() << endl;
    cout << “Age: “ << st.getAge() << endl;
    cout << “Roll Number: “ << st. getRollNumber() << endl;
    cout << “class: “ << st.getClass() << endl;
    return 0;
}


student class is publicly inherited person class using public specifier. This means everything under public in person class will be public in student class and likewise for protected and private. If we don’t mention any access specifier, then student privately inherited the person class i.e., by default it is private.

class student: private person {

};

Now, all the data members and functions become private in the student class which does not make much sense when it comes to inheritance.

Constructor of derived should take care of calling the constructor of base class as per its constructor prototype otherwise it is a compilation error. Like in this example, constructor of person class is called in the initializer list then student constructor is called.

When a student object is created, first person constructor is called (using initializer list) and then student constructor and reverse when student object is destroyed i.e., first student destructor is called then person destructor.

Size of the student class will be the size of person plus size of student. The size of derived class is independent of how it has inherited the base class i.e. either public or protected or private.

Inheritance follows “Is-A” relationship. In this case for example, student is a person. So, whenever there is “Is-A” relationship, we must use inheritance.

Code Reuse is one of strong reason of using inheritance. In this example, we have reused the person class for student class.

If you want to redefine the function of base class in the derived class, you can do it. Like for example you want to add some prints in get functions of base class and you don’t want to touch the base class functions, then you can redefine the function in the student class, then base class function will no more valid for student class.

If you want to access the base class data members in the derived class, then you can put those data members under protected access specifier in the base class. This is where protected access specifier comes in to picture. This is the only difference between private and protected access specifier.

Instead of defining own function, you want to add some prints and call base class functionality, that is also possible using scope resolution operator.

class student {
.
.
public:
    unsigned int getAge() { 
        cout << "Age: " << m_age << endl;
        return person::getAge();
    }
};

Below is the table of different type of inheritance by using different type of access specifier.



Related posts