Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess STL Modern C++ Misc Books ----

Inheritance


Contents

Calling the base class constructor

If the base class has a no argument constructor then it is called automatically when we create an object of the derived class.

File: base.cpp
#include <iostream>
using namespace std ;

class  Person
{
    public:
     string firstName  ;
     string lastName ;
     string getName()
     {
         return ( firstName + " " + lastName ) ;
     }
     Person( )
     {
         cout << "Person Constructor." << endl ;
     }
};

class Employee : public Person
{
  public:
    string jobTitle ;
    Employee( string firstNameP, string lastNameP, string jobTitleP)

         {
                 firstName = firstNameP ;
                 lastName = lastNameP ;
                 jobTitle = jobTitleP ;
         }
     void print()
     {
             cout << getName() << " " << jobTitle << endl ;
     }
};


int main()
{
  Employee e1( "Alan" , "Turing" , "Programmer" ) ;
  e1.print() ;
  return 0 ;
}
$ g++ base.cpp ; ./a.exe
Person Constructor.
Alan Turing Programmer

If the base class has a constructor then how can we call it when constructing an object of the derived class ? We can use initialization lists.

File: base1.cpp
#include <iostream>
using namespace std ;

class  Person
{
    public:
     string firstName  ;
     string lastName ;
     string getName()
     {
         return ( firstName + " " + lastName ) ;
         }
         Person( string firstNameP, string lastNameP )
         {
             firstName = firstNameP ;
             lastName = lastNameP ;
             }
             };

class Employee : public Person
{
  public:
    string jobTitle ;
    Employee( string firstNameP, string lastNameP, string jobTitleP)
                 :Person(firstNameP, lastNameP  )
         {
                 jobTitle = jobTitleP ;
         }
     void print()
     {
             cout << getName() << " " << jobTitle << endl ;
     }
};


int main()
{
  Employee e1( "Alan" , "Turing" , "Programmer" ) ;
  e1.print() ;
  return 0 ;
}


We can only call the immediate base ( parent class constructor ).There is a caveat to this in multiple inheritance.

File: base2.cpp
#include <iostream>
using namespace std ;

class  Person
{
    public:
    string firstName  ;
    string lastName ;

    void getName()
    {
        cout <<  firstName << " " <<  lastName << endl ;
    }
    Person( string firstNameP )
    {
       firstName = firstNameP ;
      cout << "Person Constructor." << endl ;
    }

    ~Person()
    {
      cout << "Person Destructor." << endl ;
    }

};

class Employee : public Person
{
    public:
     string jobTitle ;
     void getName()
     {
         cout <<  firstName << " " <<  lastName <<
         " " << jobTitle << endl ;
     }

      Employee(string firstNameP) : Person( firstNameP )
      {
            cout << "Employee Constructor." << endl ;
      }

         ~Employee()
         {
           cout << "Employee Destructor." << endl ;
         }

};

class Manager : public Employee
{
    public:
     void getName()
     {
         cout <<  firstName << " " <<  lastName <<
         " " << jobTitle <<  " Manager" << endl ;

     }
    Manager( string firstNameP ): Person( firstNameP ) , Employee( firstNameP )
    {
      cout << "Manager Constructor." << endl ;
    }


         ~Manager()
         {
           cout << "Manager Destructor." << endl ;
         }
};


int main()
{

    return 0 ;
}
$ g++ base2.cpp
base2.cpp: In constructor ‘Manager::Manager(std::string)’:
base2.cpp:64:47: error: type ‘Person’ is not a direct base of ‘Manager’
   64 |                 Manager( string firstNameP ): Person( firstNameP ) , Employee( firstNameP )

If we have same name variables in derived and base classes then we can refer to the base class variable name using the syntax "base::variable" .

File: base3.cpp
#include <iostream>
using namespace std ;


class  Person
{
    public:
    string firstName  ;
    string lastName ;

    void getName()
    {
        cout <<  firstName << " " <<  lastName << endl ;
    }
    Person( string firstNameP )
    {
       firstName = firstNameP ;
       cout << "Person Constructor." << endl ;
    }

    ~Person()
    {
      cout << "Person Destructor." << endl ;
    }

};

class Employee : public Person
{
    public:
     string jobTitle ;

     void getName()
     {
         cout <<  firstName << " " <<  lastName <<
         " " << jobTitle << endl ;

     }

          Employee(string firstNameP) : Person( firstNameP )
          {
          jobTitle = "Employee title." ;
            cout << "Employee Constructor." << endl ;
          }

         ~Employee()
         {
           cout << "Employee Destructor." << endl ;
         }

};

class Manager : public Employee
{
    public:
     string jobTitle ;
     virtual void getName()
     {
         cout <<  firstName << " " <<  lastName <<
         " " << jobTitle << Employee::jobTitle <<  " Manager" << endl ;

     }
          Manager( string firstNameP ):  Employee( firstNameP )
          {
          jobTitle = "Manager title." ;
            cout << "Manager Constructor." << endl ;
          }

         ~Manager()
         {
           cout << "Manager Destructor." << endl ;
         }
};


int main()
{
    Person* p1 ;
    Employee* e1  ;
    Manager* m1  ;
    m1 = new Manager( "Chuck" ) ;
    m1->firstName = "Chuck" ;
    m1->lastName = "Wepner" ;
    m1->jobTitle = "Boxer" ;
    m1->getName() ;
    //p1 = m1 ;
    //e1->getName() ;
    //Make sure we delete the right type
    //or program will crash
    delete m1 ;

    return 0 ;
}


Exercise

2)Modify the below program so that the constant id in the class Person is set by modifying the constructors of both the Person and Employee class.



File: ex2.cpp
#include <iostream>
using namespace std ;

class  Person
{
    public:
    string firstName  ;
    string lastName ;
    const int id ;
    string getName()
    {
        return ( firstName + " " + lastName ) ;
    }
    Person( string firstNameP, string lastNameP )
    {
            firstName = firstNameP ;
            lastName = lastNameP ;
    }
};

class Employee : public Person
{
   public:
      string jobTitle ;
      Employee( string firstNameP, string lastNameP, string jobTitleP)
                :Person(firstNameP, lastNameP  )
      {
        jobTitle = jobTitleP ;
      }
    void print()
    {
        cout << getName() << " " << jobTitle << " " << id << endl ;
    }
};


int main()
{
    Employee e1( "Alan" , "Turing" , "Programmer" , 1) ;
    e1.print() ;
    return 0 ;
}