9. Inheritance – Object-Oriented Programming with ANSI and Turbo C++

9

CHAPTER

Inheritance

C
H
A
P
T
E
R

O
U
T
L
I
N
E
—•    9.1 Introduction
—•    9.2 Access Specifiers and Simple Inheritance
—•    9.3 Protected Data with Private Inheritance
—•    9.4 Types of Inheritances
—•    9.5 Single Inheritance
—•    9.6 Multilevel Inheritance
—•    9.7 Multiple Inheritance
—•    9.8 Hierarchical Inheritance
—•    9.9 Hybrid Inheritance
—•  9.10 Multipath Inheritance
—•  9.11 Virtual Base Classes
—•  9.12 Constructors, Destructors and Inheritance
—•  9.13 Object as a Class Member
—•  9.14 Abstract Classes
—•  9.15 Qualifier Classes and Inheritance
—•  9.16 Common Constructor
—•  9.17 Pointers and Inheritance
—•  9.18 Overloading Member Function
—•  9.19 Advantages of Inheritance
—•  9.20 Disadvantages of Inheritance

9.1 INTRODUCTION

Inheritance is one of the most useful and essential characteristics of object-oriented programming. The existing classes are main components of inheritance. The new classes are created from existing one. The properties of existing classes are simply extended to the new classes. The new classes created using such methods are known as derived classes and the existing classes are known as base classes as shown in Figure 9.1. The relationship between the base and derived class is known as kind of relationship. The programmer can define new member variables and functions in the derived class. The base class remains unchanged. The object of derived class can access members of base as well as derived class. On the other hand, the object of base class cannot access members of derived classes. The base classes do not know about their subclasses.

Fig. 9.1 Inheritances

The term reusability means reuse of properties of base class in the derived classes. Reusability permits to reuse members of the previous class. In Figure 9.1 the base class is reused. Reusability is achieved using inheritance. Inheritance and reusability are not different from each other. The outcome of inheritance is reusability.

This chapter deals with implementation of the mechanism of inheritance and understand the features of it by illustrating several examples. The property of inheritance is slightly different in C++ as compared to other languages. C++ allows inheriting all the properties of previous class and there is a flexibility to add new members in the derived class, which are not available in the parent class.

The base class is called as superclass, parent or ancestor and derived class as subclass, child or descendent. It is also possible to derive a class from previously derived class. A class can be derived from more than one class.

INHERITANCE

The procedure of creating a new class from one or more existing classes is termed as inheritance.

9.2 ACCESS SPECIFIERS AND SIMPLE INHERITANCE

Before elaborating inheritance mechanism it is necessary to recall our memory for access rules studied in the chapter Classes and Objects. We have studied the access specifiers private and public in details and briefly studied the protected access specifiers previously.

The public members of a class can be accessed by objects directly outside the class i.e., objects access the data member without member function of the class. The private members of the class can only be accessed by public member function of the same class. The protected access specifier is same as private. The only difference is that it allows its derived classes to access protected members directly without member functions. This difference is explained later with suitable examples.

A new class can be defined as per the syntax given below. The derived class is indicated by associating with the base class. A new class also has its own set of member variables and functions. The syntax given next creates the derived class.

class name of the derived class: access specifiers - name of the base class
  {
     _______
     ________   // Member variables of new class (derived class)
     ______
}

The derived class name and base class names are separated by colon (:) . The access specifiers may be private or public. The keyword private or public is specified followed by colon. Generally, the access specifier is to be specified. In the absence of access specifier, the default is private. The access specifiers decide whether the characteristics of the base classes are derived privately or publicly. The derived class also has it's own set of member variables and functions. The following are possible syntaxes of declaration:

(1)

    class   B  : public A
      {
      // members of class B
      };

In the above syntax, class A is a base class, class B is a derived class. Here, class B is derived publicly.

(2)
    class   B  : private A    // private derivation
      {
      // members of class B
      };
(3)
    class   B: A    // by default private derivation
      {
      // members of class B
      };
(4)
    class   B  : protected A  //  same as private
      {
      // members of class B
      };
(5)
    Struct    B  : A  // public derivation
      {
      // Members of class B
      };

In the above syntaxes, the class B is derived privately from base class A. If no access specifier is given, the default mode is private. The use of protected access specifier give same results as private derivation. If struct is used instead of class, the default derivation is public. The following points are important to note:

(a) When a public access specifier is used, (example 1) the public members of the base class are public members of the derived class. Similarly, the protected members of the base class are protected members of the derived class.

(b) When a private access specifier is used, public and protected members of the base class are private members of the derived class.

(1) Public Inheritance

A class can be derived publicly or privately. No third type exists. When a class is derived publicly, all the public members of base class can be accessed directly in the derived class whereas in private derivation, an object of derived class has no permission to access even public members of the base class directly. In such a case, the public members of the base class can be accessed using public member functions of the derived class.

In case the base class has private member variables and a class derived publicly, the derived class can access the member variables of base class using only member functions of the base class. The public derivation does not allow the derived class to access private member variables of the class directly as is possible for public member variables. The following example illustrates public inheritance where base class members are declared as public and private.

9.1 Write a program to derive a class publicly from base class. Declare the base class with its member under public section.

# include <iostream.h>
# include <constream.h>
                          // PUBLIC DERIVATION //
class A       // BASE CLASS
{
  public:
  int x;
};


class B: public A   // DERIVED CLASS
{
  public:
  int y;
};



void main( )

{
  clrscr( );
  B b;         // DECLARATION OF OBJECT
  b.x=20;
  b.y=30;


  cout <<"\n Member of A : "<<b.x;
  cout <<"\n Member of B : "<<b.y;
}

OUTPUT

Member of A : 20
Member of B : 30

Explanation: In the above program, two classes are defined containing one public member variable each. The class B is derived publicly from the class A. Consider the statement

class B : public A

The above statement is used to derive the new class. The keyword public is used to derive the class publicly. The access specifier is followed by the base class name.

In function main( ), b is an object of class B. The object b can access the members of class A as well as of B through the following statements:

b.x=20;   //   Access to base class members
b.y=30;   // Access to derived class members

Thus, the derived class holds members of base class and its object has permission to access members of base class.

9.2 Write a program to derive a class publicly from base class. Declare the base class member under private section.

# include <iostream.h>
# include <constream.h>


                    // PUBLIC DERIVATION //


class A             // BASE CLASS
  {
     private:
     int x;
     public :

  A ( ) { x=20; }


  void showx ( )
  {
     cout <<"\n x="<<x;
  }


};


class B : public  A   // DERIVED CLASS
{
  public:
  int y;


  B ( )   {     y=30;   }


  void show ( )
  {
     showx( );
     cout <<"\n y="<<y;
  }


};


void main ( )
{


  clrscr( );
  B b;         // DECLARATION OF OBJECT
  b.show( );
}

OUTPUT

x=20
y=30

Explanation: In the above program, the class A has one private member, default constructor and member function showx( ). The class B is derived from the class A publicly. The class B contains one public member variable y, default constructor and member function show( ).

In function main( ), b is an object of derived class B. Though, the class B is derived publicly from class A, the status of members of base class remains unchanged. The object b can access public members, but cannot access the private members directly. The private members of the base class can be accessed using public member function of the base class.

The object b invokes the member function show( ) of derived class. The function show( ) invokes the showx( ) function of base class.

The object b can access member functions defined in both base and derived class. The following statements are valid:

b.showx( );     // Invokes member function of base class
b.show( );      //  Invokes member function of derived class

The constructor and member functions of derived class cannot access the private members. Due to this, separate constructor and member functions are defined in both base and derived class.

(2) Private Inheritance

The object of privately derived class cannot access the public members of the base class directly. Hence, member functions are used to access the members.

9.3 Write a program to derive a class privately. Declare the member of base class under public section.


                       // PRIVATE INHERITANCE //


# include <iostream.h>
# include <constream.h>


  class A              // BASE CLASS
  {
     public:
     int x;
};


class B : private  A   // DERIVED CLASS
{
  public:
  int y;


  B( )
  { x=20;
     y=40;
  }


  void show( )

  {  cout <<"\n x="<<x;
     cout <<"\n y="<<y;
  }
};


void main ( )
{


  clrscr( );
  B b;                 // DECLARATION OF OBJECT
  b.show( );
}

OUTPUT

x=20
y=40

Explanation: In the above program, the class B is derived privately from class A. The member variable x is a public member of base class. However, the object b of derived class cannot access directly the variable x. The following statement is invalid:

b.x=30; // cannot access

The class B is derived privately. Hence, its access is restricted. The member function of derived class can access the members of base class. The function show( ) does the same.

From the last program it is clear that handling public data of a class is not a tough task for the programmer. However, for accessing private data members, difficulties are faced by the programmer, because they cannot be accessed without member functions. Even the derived class has no permission to access private data directly. Hence, the programmer needs to define separate constructor and member functions to access the private data of that particular base class. Due to this, the length of the program increases.

9.3 PROTECTED DATA WITH PRIVATE INHERITANCE

The member functions of derived class cannot access the private member variables of base class. The private members of base class can be accessed using public member functions of the same class. This approach makes a program lengthy. To overcome the problem associated with private data, the creator of C++ introduced another access specifier called protected. The protected is same as private, but it allows the derived class to access the private members directly.

Consider the example given on the next page.

9.4 Write a program to declare protected data in base class. Access data of base class declared under protected section using member functions of derived class.

// PROTECTED DATA //

# include <iostream.h>
# include <constream.h>

  class A               // BASE CLASS
  {
     protected:         // protected declaration
     int x;
  };


class B : private A     // DERIVED CLASS
{
  int y;
  public:

     B ( )
  { x=30;
     y=40;
  }

  void show( )
  {
     cout <<"\n x="<<x;
     cout <<"\n y="<<y;
  }
};
void main( )
{
  clrscr( );
  B b;                  // DECLARATION OF OBJECT
  b.show( );
}

OUTPUT

x=30
y=40

Explanation: In this program, the data member variable of class A is declared under protected section. The class A contains neither default constructor nor any member function. The class B is derived from class A. The member functions of derived class B can access the protected member of base class.

Thus, the protected mechanism reduces the program size. The derived class doesn't need to depend upon member function of base class to access the data. The protected data protects data from direct use and allows only derived classes to access the data.

The protected access specifier must be used when we know in advance that a particular class can be used as a base class. The classes that can be used as base class, their data members must be declared as protected. In such classes programmer does not need to define functions. The member functions of base class are rarely useful.

In the inheritance mechanism, the derived classes have more number of members as compared to base class. The derived class contains properties of base class and few of its own. The object of derived class can access members of both base as well as derived class. However, the objects of base class can access the members of only base class and not of any derived class as shown in Figure 9.2. Hence, the programmer always uses objects of derived classes and performs operations. The member functions of base class cannot access the data of derived class. Obviously, the programmer uses objects of derived classes and possibly avoids defining member functions in base class.

Fig.9.2 Difference between base and derived class objects

Now that we've learnt the access specifiers in detail let us revise few points related to private, public and protected keywords. Table 9.1 gives description of access specifiers followed by explanation. Figure 9.3 gives pictorial representation of access control.

Table 9.1 Access specifiers with their scopes

(A) Accessible to member functions of the same class, derived class, and using objects. When a class is derived by private derivation, public members of the base class are private in the derived class.

(B) Accessible to member functions inside its own class but not in derived class. The derived class cannot access the private members of the base class directly. The private members of the base class can be accessed only by using public member functions of the same class.

(C) Accessible to member functions of base and derived class. When a class is derived privately, the protected members of the base class become private and when derived publicly, the protected members remain protected in the derived class.

Fig. 9.3 Access scopes of class members

The syntax of public, private and protected access specifiers are as follows:

Syntax :

  public: <declarations>

  private: <declarations>

  protected: <declarations>

If member variables of a class are protected, its scope is the same as for private. A protected member can be supposed as a hybrid of public and private members. A protected member is public for its derived class and private for other class members. Member functions and friends can use the member classes derived from the declared class only in objects of the derived type. It is possible to override the default struct access with private or protected. However, it is not possible to override the default union access. Figure 9.5 shows pictorial representation of access control in classes.

(1) All private members of the class are accessible to public members of the same class. They cannot be inherited.

(2) The derived class can access private members of the base class using member function of the base class.

(3) All the protected members of the class are available to its derived classes and can be accessed without the use of member functions of base class. In other words, we can say that all protected members act as public for the derived class.

(4) If any class is prepared for deriving classes, it is advisable to declare all members of base class as protected so that derived classes can access the members directly.

(5) All the public members of the class are accessible to its derived class. There is no restriction for accessing elements.

(6) The access specifier required while deriving classes is either private or public. If not specified, private is default for classes and public for structures.

(7) Constructors and destructors are declared in public section of the class. If declared in private section the object declared will not be initialized and compiler will flag an error.

(8) The private, public, and protected sections (visibility sections) can be defined several times in any sequence. In Figure 9.4 you can observe that public section is declared twice, private section is defined at the end and protected section is declared in between two public sections. The sections can be declared in any sequence for any number of times.

Fig. 9.4 Visibility sections

(1) Member Functions Scope

The following type of functions can have access to the protected and private members of the class. Table 9.2 describes these functions. Figure 9.5 shows access scope in classes.

Table 9.2 Access controls of functions

(A) The class member function can access the private, protected and public members.

(B) The derived class member function cannot access the private members of the base class directly. However, the private members can be accessed using member functions of the base class.

(C) The friend function of a friend class can access the private and protected members.

(D) The member function of a friend class can access the private and protected members of the class.

Fig. 9.5 Access scope in classes

9.4 TYPES OF INHERITANCES

So far we've learnt examples of simple inheritance that uses one base class and one derived class. The process of inheritance can be a simple one or may be complex.

This depends on the following points:

(1) Number of base classes: The program can use one or more base classes to derive a single class.

(2) Nested derivation: The derived class can be used as base class and new class can be derived from it. This can be possible to any extent.

Depending on the above points inheritance is classified as follows:

  • Single Inheritance

  • Multiple Inheritance

  • Hierarchical Inheritance

  • Multilevel Inheritance

  • Hybrid Inheritance

  • Multi-path Inheritance

The different types of inheritance are described in Figure 9.6. The base classes are at the top level and derived classes at the bottom. The arrow pointed from top to bottom indicates that properties of base classes are inherited by the derived class and the reverse is not applicable.

(1) Single Inheritance

When only one base class is used for derivation of a class and the derived class is not used as base class, such type of inheritance between one base and derived class is known as single inheritance. Figure 9.6 (a) indicates single inheritance.

(2) Multiple Inheritance

When two or more base classes are used for derivation of a class, it is called multiple inheritance. Figure 9.6 (b) indicates multiple inheritance.

(3) Hierarchical Inheritance

When a single base class is used for derivation of two or more classes, it is known as hierarchical inheritance. Figure 9.6 (c) indicates hierarchical inheritance.

(4) Multilevel Inheritance

When a class is derived from another derived class i.e., derived class acts as a base class, such type of inheritance is known as multilevel inheritance. Figure 9.6 (d) indicates multilevel inheritance.

(5) Hybrid Inheritance

The combination of one or more type of inheritance is known as hybrid inheritance. Figure 9.6 (e) indicates hybrid inheritance.

(6) Multipath Inheritance

When a class is derived from two or more classes that are derived from same base class such type of inheritance is known as multipath inheritance. Figure 9.6 (f) indicates multipath inheritance.

Fig. 9.6 Types of Inheritances

9.5 SINGLE INHERITANCE

When only one class is derived from a single base class such derivation of a class is known as single inheritance, further, the derived class is not used as a base class. This type of inheritance uses one base and one derived class.

The new class is termed as derived class and the old class is called as base class as shown in Figure 9.7. A derived class inherits data member variables and functions of base class. However, constructors and destructors of base class are not inherited in derived class.

The newly created class receives entire characteristics from its base class. In single inheritance, there are only one base class and derived class. The single inheritance is not as complicated as compared to other types of inheritances.

In the above diagram, class ABC is a base class and class abc is derived class. The arrow shows that class abc is derived from class ABC. The program given below illustrates single inheritance.

Fig. 9.7 Single inheritance

9.5 Write a program to show single inheritance between two classes.

# include <iostream.h>
# include <constream.h>
class ABC
{
  protected:
  char name[15];
  int age;
};


class abc : public ABC    //  public derivation
{
  float height;
  float weight;


public:


void getdata( )
{
  cout <<"\n Enter Name and Age : ";
  cin >>name>>age;

  cout <<"\n Enter Height and Weight : ";
  cin >>height >>weight;
}


void show( )
{
  cout <<"\n Name   : "<<name <<"\n Age    : "<<age<<" Years";
  cout <<"\n Height : "<<height <<" Feets"<<"\n Weight :
            " <<weight <<" Kg.";
}
};


  void main( )
{
  clrscr( );
  abc x;
  x.getdata( );      // Reads data through keyboard.
  x.show( );        //  Displays data on the screen.
}

OUTPUT

Enter Name and Age : Santosh 24

Enter Height and Weight : 4.5 50

Name  : Santosh
Age      : 24 Years
Height : 4.5 Feets
Weight : 50 Kg.

Explanation: In the above program, two classes ABC and abc are declared. The class ABC has two protected data members name and age. The class abc has two float data members height and weight with two-member functions getdata ( ) and show( ). The class abc is derived from class ABC. The statement class abc: public ABC defines the derived class abc. In function main( ), x is an object of derived class abc. The object x invokes member functions getdata( ) and show( ). This function reads and displays data respectively.

9.6 MULTILEVEL INHERITANCE

The procedure of deriving a class from derived class is named as multilevel inheritance.

Fig. 9.8 Multilevel inheritance

In the Fig. 9.8 class A3 is derived from class A2. The class A2 is derived from class A1. The class A3 is derived class. The class A2 is a derived class as well as base class for class A3. The class A2 is called as intermediate base class. The class A1 is a base class of classes A2 and A3. The series of classes A1, A2, and A3 is called as inheritance pathway as shown in Figure 9.8.

9.6 Write a program to create multilevel inheritance. Create classes A1, A2, and A3.

                        // Multilevel inheritance  //


# include <iostream.h>
# include <constream.h>


class A1                //  Base class
{
  protected :
  char name[15];
  int age;
};


class A2 : public  A1   // Derivation first level
{
  protected :
  float height;
  float weight;
};


class A3 : public A2     // Derivation second level
{
  protected :
  char sex;
  public :


  void get( )             //  Reads data
  {
     cout <<"Name    : "; cin >>name;
     cout <<"Age      : "; cin >>age;
     cout <<"Sex      : "; cin >>sex;
     cout <<"Height  : "; cin >>height;
     cout <<"Weight  : "; cin >>weight;
}

  void show( )    // Displays data
  {
     cout <<"\nName   : " <<name;
     cout <<"\nAge    : " <<age <<" Years";
     cout <<"\nSex    : " <<sex;
     cout <<"\nHeight : " <<height <<" Feets";
     cout <<"\nWeight : " <<weight <<" Kg.";
  }
};


void main( )
{
  clrscr( );
  A3 x;        // Object Declaration
  x.get( );     // Reads data
  x.show( );    // Displays data
}

 

OUTPUT

Name : Balaji
Age     : 26
Sex      : M
Height : 4
Weight : 4.9

Name  : Balaji
Age     : 26 Years
Sex      : M
Height : 4 Feets
Weight : 4.9 Kg.

Explanation: In the above program, the class A1, A2, and A3 are declared. The member variables of all these classes are protected. The class A2 is derived from class A1. The class A3 is derived from class A2. Thus, the class A2 acts as derived class as well as base class. The function get( ) reads data through the keyboard and function show( ) displays data on the screen. Both the functions are invoked using object x of class A3.

9.7 MULTIPLE INHERITANCE

Multiple inheritance is the latest addition to the C++ language. When a class is derived from more than one class then this type of inheritance is called as multiple inheritance. A class can be derived by inheriting properties of more than one class. Properties of various pre-defined classes are transferred to single derived class. Figure 9.9 shows multiple inheritance.

Fig.9.9 Multiple inheritance

9.7 Write a program to derive a class from multiple base classes.

// Multiple Inheritance //


# include <iostream.h>
# include <constream.h>


class A  {   protected :  int a; };    // class A declaration
class B  {   protected :  int b; };    // class B declaration
class C  {   protected :  int c; };    // class C declaration
class D  {   protected :  int d; };    // class D declaration


  // class E : public A, public B, public C, public D


  class E : public A,B,C,D    // Multiple derivation
  {
     int e;
     public :


     void getdata( )
  {
     cout <<"\n Enter values of a,b,c & d & e  : ";
     cin >>a>>b>>c>>d>>e;
  }


  void showdata( )
  {

cout <<"\n a="<<a <<" b = "<<b <<" c = "<<c <<" d= "<<d <<" e= "<<e;
  }
};


void main ( )
{
  clrscr( );
  E x;
  x.getdata( );  // Reads data
  x.showdata( ); // Displays data
}

OUTPUT

Enter values of a,b,c & d & e : 1 2 4 8 16
a=1 b = 2 c = 4 d= 8 z= 16

Explanation: In the above program, classes A, B, C, D, and E are declared each with one integer member variable. The class E has two-member functions, getdata( ) and showdata( ). The getdata ( ) is used to read integers through the keyboard and showdata( ) is used to display the contents on the screen. The class E is derived from the classes A, B, C, and D. The classes A, B, C, and D all together act as a base class. The derivation is carried out with the statement class E: public A, B, C, and D. The class members of A are publicly derived and members of other classes are privately derived. To derive all class members publicly, the statement would be as class Z: public A, public B,public C, public D. Remember that the meaning of both the statements is not the same. Most programmers refer to the second format as it reduces the code.

9.8 HIERARCHICAL INHERITANCE

We know that in inheritance, one class could be inherited from one or more classes. In addition, new members are added to the derived class. Inheritance also supports hierarchical arrangement of programs. Several programs require hierarchical arrangement of classes, in which derived classes share the properties of base class. Hierarchical unit shows top down style through splitting a compound class into several simple sub classes. Figure 1.16 given in Chapter “Introduction to C++”, is a perfect example of hierarchy of classes. The program based on hierarchical inheritance is illustrated below.

9.8 Write a program to show hierarchical inheritance.

# include <constream.h>
# include <iostream.h>


class red
{

  public:
  red ( ) {cout<<" Red  ";};
};


class yellow
{
  public :
  yellow( ) { cout <<" Yellow "; }
};


class blue
{
  public:
  blue ( ) { cout <<" Blue "; }
};


class orange : public red, public yellow
{
  public :
  orange( )    {      cout <<"  = Orange ";     }
};


class green : public blue, public yellow
{
  public:
  green( ) {   cout <<"  = Green "; }


};


class violet : public red, public blue
{
  public:
  violet( ) { cout <<"   = Violet "; }
};


class reddishbrown : public orange, public violet
{
  public:
  reddishbrown( ) { cout <<" = Reddishbrown "; }
};

class yellowishbrown : public green, public orange
{
  public:
  yellowishbrown( ) { cout<<" = Yellowishbrown "; }
};


class bluishbrown : public violet, public green
{
  public:
  bluishbrown( ) { cout<<"  = Bluishbrown "; }
};


void main( )
{
  clrscr( );
  reddishbrown r;
  endl(cout);


  bluishbrown b;
  endl(cout);


  yellowishbrown y;
  endl(cout);
}

OUTPUT

Red Yellow = Orange Red Blue = Violet = Reddishbrown
Red Blue = Violet Blue Yellow = Green = Bluishbrown
Blue Yellow = Green Red Yellow = Orange = Yellowishbrown

Explanation: For each colour separate class with constructor is declared. The classes red, blue, and yellow are base classes. The class orange is derived from classes red and yellow. The class green is derived from blue and yellow. The class violet is derived from red and blue.

The class reddishbrown is derived from classes orange and violet. The class yellowishbrown is derived from classes green and orange and lastly the class bluishbrown is derived from violet and green.

In function main ( ) , objects of classes reddishbrown , yellowishbrown, and bluishbrown are declared. When objects are declared constructors are executed from base to derived classes. Constructor when executed displays the class name (colour name). The output shows names of different colours and resulting colour after their combination.

9.9 HYBRID INHERITANCE

The combination of one or more types of inheritance is known as hybrid inheritance. Sometimes, it is essential to derive a class using more types of inheritances. Figure 9.10 shows hybrid inheritance. In the diagram given below the class GAME is derived from two base classes i.e., LOCATION and PHYSIQUE. The classPHYSIQUE is also derived from class player.

Fig. 9.10 Hybrid inheritance

9.9 Write a program to create a derived class from multiple base classes.

// Hybrid Inheritance //


# include <iostream.h>
# include <constream.h>


class PLAYER
{
  protected :
  char name[15];
  char gender;
  int  age;
};


class PHYSIQUE : public PLAYER
{
  protected :
  float height;
  float weight;
};


class LOCATION
{
  protected :
  char city[10];
  char pin[7];
};

class GAME : public PHYSIQUE, LOCATION
{
protected :
char game[15];
public :
void getdata( )
{
  cout <<" Enter Following Information\n";
  cout <<"Name    : "; cin>> name;
  cout <<"Gender  : "; cin>>gender;
  cout <<"Age     : "; cin>>age;
  cout <<"Height  : "; cin>>height;
  cout <<"Weight  : "; cin>>weight;
  cout <<"City     : "; cin>>city;
  cout <<"Pincode : "; cin>>pin;
  cout <<"Game     : "; cin>>game;
}
void show( )
{
  cout <<"\n Entered Information";
  cout <<"\nName     : "; cout<<name;
  cout <<"\nGender  : "; cout<<gender;
  cout <<"\nAge     : "; cout<<age;
  cout <<"\nHeight  : "; cout<<height;
  cout <<"\nWeight  : "; cout<<weight;
  cout <<"\nCity     : "; cout<<city;
  cout <<"\nPincode : "; cout<<pin;
  cout <<"\nGame     : "; cout<<game;
}
};


int main( )

{
  clrscr( );
  GAME G;
  G.getdata( );
  G.show( );
  return 0;
}

OUTPUT

Enter Following Information
Name    : Mahesh
Gender  : M
Age        : 25
Height   : 4.9
Weight   : 55
City       : Nanded
Pincode : 431603
Game    : Cricket
Entered Information
Name    : Mahesh
Gender : M
Age       : 25
Height   : 4.9
Weight : 55
City      : Nanded
Pincode : 431603
Game     : Cricket

Explanation: In the above program, PLAYER, PHYSIQUE, LOCATION, and GAME classes are defined. All the data members of these four classes are protected. The class PHYSIQUE is derived from base class PLAYER. The class GAME is derived from PHYSIQUE and LOCATION i.e., the derived class GAME has two base classes PHYSIQUE and LOCATION. The class LOCATION is a separate class and not derived from any other class. The getdata( ) and show( ) are functions of class GAME which read and display data respectively. In main( ), the object G of class GAME calls these functions one by one to read and write the data. The output of the program is shown at the end of the above program.

9.10 MULTIPATH INHERITANCE

When a class is derived from two or more classes, which are derived from the same base class such type of inheritance is known as multipath inheritance. Multipath inheritance consists of many types of inheritances such as multiple, multilevel and hierarchical as shown in Figure 9.11.

Consider the following example:

class A1
{
  protected:
  int a1;
};

class A2 : public A1
{

  protected:
  int a2;
};

class A3: public  A1
{
  protected:    int a3;
};


class A4: public A2,A3
{int a4;             };

Fig. 9.11 Ambiguity in classes

In the given example, class A2 and A3 are derived from the same base class i.e., class A1 (hierarchical inheritance). The classes A2 and A3 both can access variable a1 of class A1. The class A4 is derived from class A2 and class A3 by multiple inheritances. If we try to access the variable a1 of class A, the compiler shows error messages as given below.

(a) Error PRG58.CPP 30: Member is ambiguous: ‘A1::a1’ and ‘A1::a1’

(b) Error PRG58.CPP 37: Member is ambiguous: ‘A1::a1’ and ‘A1::a1’

In the above example, we can observe all types of inheritances i.e. multiple, multilevel and hierarchical. The derived class A4 has two sets of data members of class A1 through the middle base classes A2 and A3. The class A1 is inherited twice.

9.11 VIRTUAL BASE CLASSES

To overcome the ambiguity occurred due to multipath inheritance, C++ provides the keyword virtual. The keyword virtual declares the specified classes virtual. The example given below illustrates the virtual classes.

class A1
{
  protected:
  int a1;
};


class A2 : virtual public A1    // virtual class declaration
{
  protected:
  int a2;
};


class A3: virtual public  A1    // virtual class declaration
{
  protected:
  int a3;
};

class A4: public A2,A3
{
int a4;
};

When classes are declared as virtual, the compiler takes necessary precaution to avoid duplication of member variables. Thus, we make a class virtual if it is a base class that has been used by more than one derived class as their base class.

Let us consider an example that will give a clear idea of virtual classes as well as necessary care to be taken while declaring them.

(a) A base class cannot be specified more than once in a derived class.

class A
{ _____
_____ };


class A1: A, A { ... };  // Illegal Declaration

Here, class A is specified twice. Hence, it is an illegal declaration.

(b) A base class can be indirectly passed to the derived class more than once.

     class L: public A { ... }

     class K: public A { ... }

     class J: public L, public K { ... } // Legal declaration

In the above case (b), each object of class J will contain two sub-objects of class A through classes L and K.

(c) Case (b) causes some problems. To avoid duplication we can add the keyword virtual to a base class specifier.

For example,

     class L : virtual public A { ... }

     class K : virtual public A { ... }

     class J : public K, public J { ... }

The virtual keyword always appears before the class name. A is now a virtual base class, and class J has only one sub-object of class A.

9.10 Write a program to declare virtual base classes. Derive a class using two virtual classes.

// VIRTUAL BASE CLASSES  //

# include <iostream.h>
# include <conio.h>

     class A1
     {
      protected:
      int a1;
     };

     class A2 : public virtual A1    // virtual declaration
     {
      protected :
      int a2;
     };

     class A3 : public virtual A1   // virtual declaration
     {
      protected:
      int a3;
     };

     class A4 : public A2,A3  // virtual declaration
     {
     int a4;
     public :

     void get( )
     {
     cout <<"Enter values for a1, a2,a3 and  a4 : ";
     cin >>a1>>a2>>a3>>a4;
     }

     void put( )
     {
     cout <<"a1= "<<a1 <<" a2 = "<<a2 <<" a3 = "<<a3 <<"a4 = "<<a4;
     }
};

void  main( )
{

     clrscr( );
     A4 a;
     a.get( );    // Reads data
     a.put( );   // Displays data
}

OUTPUT

Enter values for a1 a2,a3 and a4 : 5 8 7 3
a1= 5 a2 = 8 a3 = 7 a4 = 3

Explanation: In the above program, the classes A1, A2, A3, and A4 are declared and each contains one protected member variable. The class A4 has two member functions get( ) and put( ). The get( ) function reads integers through the keyboard. The put( ) function displays the contents of the member variables on the screen. The classes A2 and A3 are derived from class A1. While deriving these two classes, the class A1 is declared as virtual as per the following statements:

(a) class A2 : public virtual A1 // derivation of class A2

(b) class A3 : public virtual A1 // derivation of class A3

(c) class A4: public A2,A3 // derivation of class A4

The class A4 is derived from two classes A2 and A3 as per the statement (c). In function main( ), the object a of class A4 invokes the member function get( ) and put( ).

9.12 CONSTRUCTORS, DESTRUCTORS AND INHERITANCE

The constructors are used to initialize member variables of the object and the destructor is used to destroy the object. The compiler automatically invokes constructors and destructors. The derived class does not require a constructor if the base class contains zero-argument constructor. In case the base class has parameterized constructor then it is essential for the derived class to have a constructor. The derived class constructor passes arguments to the base class constructor. In inheritance, normally derived classes are used to declare objects. Hence, it is necessary to define constructor in the derived class. When an object of a derived class is declared, the constructors of base and derived classes are executed.

In inheritance, destructors are executed in reverse order of constructor execution. The destructors are executed when an object goes out of scope. To know the execution of constructor and destructor let us study the following program.

9.11 Write a program to show sequence of execution of constructor and destructor in multiple inheritance.

# include <iostream.h>
# include <constream.h>


class A    // base class

{
  public :
  A ( )
  { cout <<"\n Zero-argument constructor of base class A";  }


  ~A( )


  { cout<<"\n Destructor of the class A"; }


};


  class B  //  base class
  {
     public:
  B( )
  { cout<<"\n Zero-argument constructor of base class B "; }


  ~B( ) { cout <<"\n Destructor of the class B " ; }
  };


  class C : public A, public B    // Derivation of class
  {
     public:
  C( )
  {  cout <<"\n Zero-argument constructor of derived class C";
  }


  ~C( )   { cout<<"\n Destructor of the class C";   }


  };


  void  main( )
  {
  clrscr( );
  C objc;   // Object declaration
  }

 

OUTPUT

Zero-argument constructor of base class A
Zero-argument constructor of base class B
Zero-argument constructor of derived class C
Destructor of the class C
Destructor of the class B
Destructor of the class A

Explanation: In the above program, class A and B are two classes. The class C is derived from classesA andB. The constructors of base classes are executed first followed by derived class. The destructors of derived classes are executed first followed by base class.

(1) Base and Derived Classes with Constructor

9.12 Write a program to declare both base and derived classes with constructors.

# include <iostream.h>
# include <conio.h>


class I
{
public :


I( )
{
  cout <<"\n In base class constructor ";   }
};


class II : public I
{
  public:
II( )   {     cout <<"\n In derived class constructor\n";
}


};


void main( )
{
  clrscr( );
  II i;
}

OUTPUT

In base class constructor
In derived class constructor

Explanation: In the above program, both the base and derived classes contain constructors. When the object of derived class type is declared and constructors of both the classes are executed, the constructor of base class is executed first and then the constructor of derived class.

(2) Base Class with Various Constructors and Derived Class with One Constructor

9.13 Write a program to declare multiple constructors in base class and single constructor in derived class.

# include <iostream.h>
# include <conio.h>


class I
{
  public :
  int x;



  I( )    { cout <<"\nZero argument base class constructor "; }


  I( int k)
  {
     cout <<"\nOne argument base class constructor";
  }


};


class II : public I
{
  int y;
  public:


  II (int j)
  {
     cout <<"\nOne argument derived class constructor ";
     y=j;
  }
};



void main( )
{

  clrscr( );
  II i(2);
}

OUTPUT

Zero argument base class constructor
One argument derived class constructor

Explanation: In the above program, the class I has zero and one argument constructor. The class II has only one argument constructor. The object i is declared with an integer. The zero argument constructor of base class and one argument constructor of derived class are executed.

(3) Base and Derived Classes without Default Constructor

9.14 Write a program to declare base and derived class without default constructor.

# include <iostream.h>
# include <conio.h>


class I
{
  public :
  int x;


   I ( int k)
   {
   x=k;
   cout <<"\nOne argument base class constructor";   }


};


class II : public I
{
  int y;
  public:


II (int j) : I(j)
  {
     cout <<"\nOne argument derived class constructor ";

     y=j;
  }
};


void main( )
{
  clrscr( );
  II i(2);
}

OUTPUT

One argument base class constructor
One argument derived class constructor

Explanation: In the above program, no default constructor is declared. In class II one argument constructor is declared and base class constructor is explicitly invoked. When object i is declared, one argument constructor of both the classes is executed. In the absence of explicit call of base class constructor the compiler will display the error message “Cannot find default constructor to initialize base class ‘I’”.

(4) Constructors and Multiple Inheritance

9.15 Write a program to derive a class using multiple base classes. Observe the execution of constructor when object of derived class is declared.

# include <iostream.h>
# include <conio.h>


class I
{
  public:


I( ) { cout <<"\n Zero argument constructor of base class I "; }


};


class II
{
  public:


  II( ) { cout<<"\n Zero argument constructor of base class II ";}

};


class III : public II,I
{
public:


III( )
{ cout<<"\n Zero argument constructor of base class III "; }


};


void main( )
{
  clrscr( );
  III i;
}

OUTPUT
Zero argument constructor of base class II
Zero argument constructor of base class I
Zero argument constructor of base class III

Explanation: The classes I and II are base classes of derived class III. In function main( ), i is an object of derived class III. The execution of constructors depends on the sequence given while deriving a class as per the following statement:

  class III : public II,I

Here, the class II is the first base class and class I is the second base class and the execution sequence of constructors is shown in the output.

(5) Constructors in Multiple Inheritances with Explicit Call

9.16 Write a program to derive a class using multiple base classes. Invoke the constructors of base classes explicitly.

# include <iostream.h>
# include <conio.h>


class I
{
  public:


I( ) { cout <<"\n Zero argument constructor of base class I "; }

};


class II
{
  public:


  II( ) { cout<<"\n Zero argument constructor of base class II ";}
};


class III : public II,I
{
public:


III( ) : II( ), I( )
{ cout<<"\n Zero argument constructor of base class III "; }
};


void main( )
{
  clrscr( );
  III i;
}

OUTPUT
Zero argument constructor of base class II
Zero argument constructor of base class I
Zero argument constructor of base class III

Explanation: In this program, in class III explicitly, the constructors of both the base classes II and I are invoked. The execution sequence can be observed in the output. The execution sequence of constructor depends on the sequence of base classes and not according to the explicit calls.

(6) Multiple Inheritance and Virtual Class

9.17 Write a program to derive a class using multiple base classes. Invoke the constructors of base classes explicitly. Declare any one base class as virtual.

# include <iostream.h>
# include <conio.h>


class I
{
  public:
  I( ) { cout <<"\n Zero argument constructor of base class I "; }

};


class II
{
  public:


  II( ) { cout<<"\n Zero argument constructor of base class II ";}
};


class III : public II, virtual I
{
public:


III( ) : II( ), I( )
{ cout<<"\n Zero argument constructor of base class III "; }


};


void main( )
{
clrscr( );
III i;
}

OUTPUT
Zero argument constructor of base class I
Zero argument constructor of base class II
Zero argument constructor of base class III

Explanation: In this program, the base class I is declared as virtual class while deriving the class. The constructor of virtual class is executed first. The execution of constructor here is not according to the sequence of base class.

(7) Execution of Constructors in Multilevel Inheritance

9.18 Write a program to derive a class using multilevel inheritance and observe the execution sequence of constructors.

# include <iostream.h>
# include <conio.h>

class I
{
  public:
  I( ) { cout <<"\n Zero argument constructor of base class I "; }
};


class II : public I
{
  public:
  II( ) { cout<<"\n Zero argument constructor of base class II ";}
};


class III : public II
{
  public:
  III( ) { cout<<"\n Zero argument constructor of base class III "; }
};


void main( )
{
  clrscr( );
  III ii;
}

OUTPUT
Zero argument constructor of base class I
Zero argument constructor of base class II
Zero argument constructor of base class III

Explanation: In this program, the class II is derived from class I. The class III is derived from class II. The class II is base as well as derived class. In function main ( ), ii is an object of class III. The constructors are executed from base to derived classes as shown in the output. Table 9.3 shows order of execution of constructors.

Table 9.3 Execution sequences of constructors

Statements Sequence of execution Remarks
Class II : public I I ( ) – Base class constructor
II ( )- Derived class constructor
Single inheritance
Class III: public I, II I ( ) – Base class constructor
II ( )- Base class constructor
III ( )- Derived class constructor
Multiple inheritance
Class III: public I, virtual II


class II : public I
{};



class III: public II {};
II ( ) – Virtual class constructor
I ( ) – Base class constructor
III ( ) – Derived class constructor
I ( ) – First base class constructor
II ( ) – second base class constructor
III ( ) – derived class constructor
Multiple inheritance

Multiple inheritance

9.13 OBJECT AS A CLASS MEMBER

Properties of one class can be used in another class using inheritance or using object of a class as a member in another class. Declaring object as a class data member in another class is also known as delegation. When a class has an object of another class as its member, such class is known as container class.

In inheritance, derived classes can use members of base class. Here, the derived class is a kind of base class. The programmer can also add new members to the derived class.

In delegation, the class is composed from objects of another classes. The composed class uses properties of other classes through their objects. This kind of relationship is known as has-a-relationship or containership.

class I
{
  ***** // members
  *****
}

class II
{
  I J; // object of class I as member
  ******
}

9.19 Write a program to use object of one class in another class as a member.

# include <iostream.h>
# include <conio.h>


class I
{
  public:
  int x;


I( )

     {
       cout <<"\n Constructor of class I";
       x=20;
     }
};


class II
{
  public:
  int k;
  I y;


  II( )
  {
     k=30;
     cout <<"\n Constructor of class II";
    }


void show( ) { cout <<"\n x= "<<y.x <<" k = "<<k; }
};


void main( )
{
  clrscr( );
  II ii;
  ii.show( );
}

OUTPUT
Constructor of class I
Constructor of class II
x= 20 k = 30

Explanation: In the above program, class II contains integer k and object y of class I. In function main( ), object ii is an object of class II. The constructor of class I is executed first because when compiler reaches class II, it finds an object of class I. We know that object declaration always executes constructors of that class. Thus, object of class I is declared and constructor of class I is executed. The constructor of class II is executed and variable of class II is initialized. The member function show( ) displays the contents of x and k. The contents of class I member is obtained from object y. The dot (.) operator is used to access the elements of class I.

9.20 Write a program to access member variables of base class using object, scope access operator and direct.

# include <iostream.h>
# include <conio.h>


class A1
{
  public  :
  char name[15];
  int age;
};


class A2 : public A1
{
  private :
  A1 a;
float height;
float weight;
  public :


     A2( )
       {
     clrscr( );



     cout <<"Access Using Scope Access operator\n";


     cout <<"Name    : "; cin>>A1::name;
     cout <<"Age      : "; cin>>A1::age;


     cout <<"Access Using object of the class\n";


     cout <<"Name   : "; cin >>a.name;
     cout <<"Age       : "; cin >>a.age;
     cout <<"Access Using direct member variables\n";


     cout <<"Name   : "; cin >>name;
     cout <<"Age      : "; cin >>age;

      cout <<"Height  : "; cin >>height;
      cout <<"Weight : "; cin >>weight;
  }


  ~A2( )


  {
      cout <<"\nDisplay using Scope Access operator\n";


      cout <<"\nName  : " <<A1::name;
      cout <<"\nAge     : " <<A1::age;


      cout <<"\nDisplay Using object of the class\n";


      cout <<"\nName  : " <<a.name;
      cout <<"\nAge     : " <<a.age;


      cout <<"\nAccess Using direct member variables\n";


      cout <<"\nName  : " <<name;
      cout <<"\nAge     : " <<age;


      cout <<"\nHeight  : " <<height;
      cout <<"\nWeight : " <<weight;
  }
};


void main( )
{
A2 x;
}

OUTPUT
Name : Ajay
Age    : 21
Access Using object of the class
Name : Amit
Age    : 20
Access Using direct member variables
Name : Arun
Age    : 19
Height : 5.5
Weight : 31

Display using Scope Access operator
Name : Arun
Age    : 19
Display Using object of the class
Name : Amit
Age : 20
Access Using direct member variables
Name : Arun
Age    : 19
Height : 5.5
Weight : 31

Explanation: In the above program, A1 and A2 are two classes. The class A2 is derived from class A1. Class A1 has two public member variables. Class A2 has three private members. One of it's member is an object of class A1 i.e., object a. The object a holds its separate set of member variables of class A1. There are three ways to access member variables of base class A1. Table 9.4 describes status of access of member variables of class A1 through derived class A2 when we use access specifiers such as private, public and protected.

Table 9.4 Access specifiers

(1) The first way is to use scope access operator as given below:

  cin>>A1::name;

  cin>>A1::age;

In the above statements, A1 is a class name and name and age are member variables of class A1. When access specifier is public or protected the above statements are valid.

(2) The second method is to use objects of the base class as given below:

  cin >>a.name;

  cin >>a.age;

In the above statements, member variables of class A1 are accessed using objects of the same class, which is the member of the derived class. This is possible only when the member variables of class A1 are public and not possible if the member variables of class A1 are protected or private.

(3) The third method uses directly the member variables. Direct access is possible when access specifier is public or protected, as per the following statements.

  cin >>name;

  cin >>age;

9.21 Write a program to derive a class from two base classes. Use objects of both the classes as member variables for derived class. Initialize and display the contents of classes using constructor and destructor.

# include <iostream.h>
# include <conio.h>


     class A
     {
       public :
       int  a1;
     };


     class B
     {
       public:
       int b1;
     };


     class AB
     {
       public :
       A a;
       B b;
     public :


     AB ( )
     {
     a.a1=65;
     b.b1=66;
     cout <<"a1 = "<<a.a1 <<" b1 = "<<b.b1;
     }


     ~AB( ){ };
};


int main( )
{

clrscr( );
AB ab;


return 0;
}

OUTPUT

a1=65 b1=66

Explanation: In the above program, class A and class B are declared each with one integer. Class AB is declared which contains objects of A and B classes as member variables. The constructor of class AB initializes member variables of class A and B. The constructor also displays contents on the screen. Finally, the destructor destroys the object.

9.14 ABSTRACT CLASSES

When a class is not used for creating objects it is called as abstract class. The abstract class can act as a base class only. It is a lay out abstraction in a program and it allows a base on which several levels of inheritance can be created. The base classes act as foundation of class hierarchy. An abstract class is developed only to act as a base class and to inherit and no objects of these classes are declared. An abstract class gives a skeleton or structure, using which other classes are shaped. The abstract class is central and generally present at the starting of the hierarchy. The hierarchy of classes means chain or groups of classes being involved with one another. In the last program, class A is an abstract class because no instance (object) of class A is declared.

9.15 QUALIFIER CLASSES AND INHERITANCE

The following program explains the behaviour of qualifier classes and the classes declared within them with inheritance.

9.22 Write a program to create derived class from the qualifier class.

# include <iostream.h>
# include <conio.h>


class A
{
      public:
      int x;
      A ( ) {}


           class B
           {

             public:
             int y;
                 B( ) {}
      };


};    class C  : public A,A::B
      {
             public:
             int z;


      void show( )
      {
           cout <<endl<<"x = "<<x <<" y ="<<y<<" z = "<<z;
      }


           C (int j,int k, int l)
             {
                 x=j;
                 y=k;
                 z=l;
             }
      };


void main( )
{
  clrscr( );
  C c(4,7,1);
  c.show( );
}

OUTPUT

x = 4 y =7 z = 1

Explanation: In the above program, class B is defined inside class A. The class A is a qualifier class of class B. The class C is inherited from the classes A and B. In the statement class C: public A, A::B, class C is inherited from A and B. To access class B, it is preceded by the qualifier class A and scope access operator. If we mention only class A, class B won't be considered for inheritance. Similarly, if we mention only class B, the qualifier class A will not be considered for inheritance.

9.16 COMMON CONSTRUCTOR

When a class is declared, constructor is also declared inside the class in order to initialize data members. It is not possible to use a single constructor for more classes. Every class has its own constructor and destructor with the same name as class. When a class is derived from another then it is possible to define a constructor in derived class and data members of both base and derived classes can be initialized. It is not essential to declare constructor in a base class. Thus, the constructor of the derived class works for its base class and such constructors are called as common constructors.

9.23 Write a program to initialize member variables of both base and derived classes using a constructor of derived class.

# include <iostream.h>
# include <conio.h>


class A
{
  protected:
  int x;
  int y;


};


class B : private A
{
  public:
  int z;


B( ) {   x=1,y=2,z=3;
  cout <<"x= "<<x << " y ="<<y <<" z="<<z; }


}
};


void main( )
{
  clrscr( );
  B b;
}

OUTPUT
x= 1 y =2 z=3

Explanation: In the above program, class A and class B are declared. Class B is derived from class A. The constructor of class B initializes member variables of both classes. Hence, it acts as a common constructor of both base and derived class.

9.17 POINTERS AND INHERITANCE

The private and public member variables of a class are stored in successive memory locations. A pointer to public member variable gives us access to private member variables.

The same is true for derived class. The member variables of base class and derived class are also stored in successive memory locations. The following program explains the mechanism of accessing private data members of the base class using the address of public member variable of derived class using pointer. Here, no member functions are used.

9.24 Write a program to access private member variables of base class using pointers.

# include <iostream.h>
# include <conio.h>


class A
{
  private:
  int x;
  int y;


  public:


  A( ) {
     x=1;
     y=2;
       }
};
class B : private A
{
public:
int z;


B( ) { z=3; }


};


void main( )
{
 clrscr( );
B b;   // object declaration
int *p;// pointer declaration
p=&b.z; // address of public member variabe is stored in pointer

cout<<endl<<" Address of z : "<<(unsigned)p <<" "<<"Value of z :"<<*p;
p--;  // points to previous location
cout<<endl<<" Address of y : "<<(unsigned)p <<" "<<"Value of y :"<<*p;
p--;
cout<<endl<<" Address of x : "<<(unsigned)p <<" "<<"Value of x :"<<*p;
}

OUTPUT
Address of z : 65524 Value of z :3
Address of y : 65522 Value of y :2
Address of x : 65520 Value of x :1

Explanation: In the above program, class A contains two private member variables x and y. The constructor initializes the member variables. Class B is derived from class A. The class B has one public member variable. In function main( ), b is an object of class B. The pointer p is an integer pointer. The address of member variable z of derived class B is assigned to pointer p. By applying decrease operation, we get the previous memory locations where member variables of base classes are stored. The values of all member variables with their addresses are displayed.

9.18 OVERLOADING MEMBER FUNCTION

The derived class can have the same function name as base class member function. An object of the derived class invokes member functions of the derived class even if the same function is present in the base class.

9.25 Write a program to overload member function in base and derived class.

# include <iostream.h>
# include <constream.h>


class B
{
  public:


  void show( )
  {
     cout <<"\n In base class function ";
  }
};


class D : public B
{

  public:


  void show( )
  {
     cout <<"\n In derived class function";
  }


};



int main( )
{
  clrscr( );
  B b;           // b is object of base class
  D d;           // d is object of derived class


  b.show( );      // Invokes Base class function
  d.show( );      // Invokes Derived class function
  d.B::show( );   // Invokes Base class function
  return 0;
}

OUTPUT
In base class function
In derived class function
In base class function

Explanation: In this program, class D is derived from class B. Both the classes have the same function show( ) as member function. In function main( ), objects of both B and D classes are declared. The object b invokes the member function show( ). The object b is object of base class, hence, it invokes the member function show( ) of base class. In addition, the objects of base class cannot invoke the member functions of derived class, because the base class does not have information about the classes derived under it.

The object d of derived class invokes the function show( ). When function with same name and argument list are present in both the base and derived classes, the objects of derived class give first priority to function of its own class. Thus, the statement d.show( ) invokes function of derived class. To invoke the function of base class with the object of derived class, the class name and scope access operator are preceded before the matching function name. From the above program, it is also clear that we can declare objects of both base and derived classes. The objects of both base and derived classes are independent of each other.

9.19 ADVANTAGES OF INHERITANCE

(1) The most frequent use of inheritance is for deriving classes using existing classes, which provides reusability. The existing classes remain unchanged. By reusability, the development time of software is reduced.

(2) The derived classes extend the properties of base classes to generate more dominant object.

(3) The same base classes can be used by a number of derived classes in class hierarchy.

(4) When a class is derived from more than one class, all the derived classes have the same properties as that of base classes.

9.20 DISADVANTAGES OF INHERITANCE

(1) Though object-oriented programming is frequently propagandized as an answer for complicated projects, inappropriate use of inheritance makes a program more complicated.

(2) Invoking member functions using objects create more compiler overheads.

(3) In class hierarchy various data elements remain unused, the memory allocated to them is not utilized.

SUMMARY

(1) Inheritance is one of the most useful and essential characteristics of object-oriented programming language. Inheritance allows the programmer to utilize the previously defined classes with newer ones. The new class is assembled using properties of existing classes.

(2) The procedure of developing a new class from an old class is termed as inheritance.

(3) The new class is termed as derived class and the old class is called base class.

(4) Single inheritance When a new class is derived from only one base class such type of inheritance is called as single inheritance.

(5) Multilevel inheritance The procedure of deriving a class from derived class is named as multilevel inheritance.

(6) Multiple inheritance or Hierarchical inheritance When a class is derived from more than one class then this type of inheritance is called as multiple inheritance or hierarchical inheritance.

(7) Hybrid inheritance When a class is derived from another one or more base classes, this process is termed as hybrid inheritance.

(8) When classes are declared as virtual, the compiler takes essential caution to avoid duplication of member variables. Thus, we make a class virtual if it is a base class that has been used by more than one derived class as their base class.

(9) Execution of constructor in inheritance The execution of constructor takes place from base class to derived class.

(10) Execution of destructor in inheritance The execution of destructors is in opposite order as compared to constructors i.e., from derived class to base class.

(11) Public If member variables of a class are public, any function can access them. In C++, members of struct and union are by default public.

(12) Private If member variables of a class are private, member functions and friends can only access them, if they are declared in the same class. Members of a class are by default private.

(13) Protected If member variables of a class are protected, its scope is the same as for private. In addition, member functions and friends can use the member classes derived from the declared class but only in objects of the derived type.

(14) When a class is not used for creating objects, it is called as abstract class.

(15) The constructor of the derived class works for its base class; such constructors are called as common constructors.

(16) The derived class can have the same function name as the base class member function. An object of the derived class invokes member functions of the derived class even if the same function is present in the base class.

(17) Properties of one class can be used in another class using inheritance or using objects of a class as a member in another class. Declaring objects as a class data member in another class is also known as delegation. When a class has an object of another class as its member, such class is known as container class.

EXERCISES

[A] Answer the following questions.

(1) What do you mean by inheritance?

(2) What do you mean by base class and derived class?

(3) Describe various types of inheritances with examples.

(4) What is the difference between single and multilevel inheritance?

(5) What is the difference between multilevel and hybrid inheritance?

(6) How are constructors and destructors executed in multilevel inheritance?

(7) What is the use of virtual keyword?

(8) What do you mean by virtual classes?

(9) What are abstract classes?

(10) Describe the use of public, private and protected access specifiers.

(11) What are nested classes?

(12) Explain the mechanism for accessing private member of the base class using pointers.

(13) What is the difference between private and protected access specificiers?

(14) Do you think that accessing private data using pointers is a limitation of encapsulation?

(15) How do structure and class provide inheritance differently?

(16) What is the difference between private and protected inheritance?

(17) What are the advantages and disadvantages of inheritance?

(18) What do you mean by object delegation?

(19) What is a common constructor?

(20) Explain hierarchical inheritance.

[B] Answer the following by selecting the appropriate option.

(1) What will be the output of the following program? class A { public: int a;

class A
{  public:
     int a;
        A( ) {a=10;}
};


     class B : public A
     {  public:
     int b;
     B( ) { b=20; }
     ~ B( )  {  cout <<"\n a= "<<a <<" b = "<<b;}
};

};

  void main ( ) { B( );}

(a) a = 10 b = 20

(b) a = 20 b = 10

(c) a = 30 b = 30

(d) none of the above

(2) Identify the access specifier

(a) public

(b) virtual

(c) void

(d) class

(3) An object a cannot access the variable class A

class A
{  public:
   int a;
   private:
   int b;
   public:
   A( ){a=10,b=20;}
};
void main( ){ A a;}

(a) b

(b) a

(c) both (a) and (b)

(d) both a and b are accessible

(4) Private data members of a class can be accessed by

(a) public member functions of the same class

(b) directly by the object

(c) private member function of the same class

(d) none of the above

(5) In multilevel inheritance, the middle class acts as

(a) base class as well as derived class

(b) only base class

(c) only derived class

(d) none of the above

(6) In single inheritance, constructors are executed from

(a) base class to derived class

(b) derived class to base class

(c) both (a) and (b)

(d) none of the above

(7) In the following program object of which class can access all member variables?

struct A  { int x;  };

struct B : A  { int y;  };

struct C : B  { int z;  };

struct D : C { int k; };

(a) object of class D

(b) object of class B

(c) object of class C

(d) object of class A

The protected keyword allows

(a) derived class to access base class members directly

(b) prevents direct access to public members

(c) allows objects to access private members

(d) all of the above

(9) The class is declared virtual when

(a) two or more classes involved in inheritance have common base class

(b) more than one class is derived

(c) we want to prevent a base class from inheritance

(d) none of the above

(10) The ambiguity of members normally occurs in

(a) single inheritance

(b) multilevel inheritance

(c) multiple inheritance

(d) none of the above

(11) In the following program class A is an

class  A {   int x; };
class  B :  A   {    int y;  };


void main ( )  {      B b;   }

(a) abstract class

(b) virtual class

(c) derived class

(d) none of the above

(12) Class A is a base class of class B. The relationship between them is

(a) kind of relationship

(b) has a relationship

(c) is a relationship

(d) none of the above

[C] Attempt the following programs.

(1) Write a program to define three classes A, B and C. Each class contains private data members. Derive class C from A and B by applying multiple inheritance. Read and display the data using constructors and destructors.

(2) Write a program to declare classes X, Y and Z. Each class contains one character array as a data member. Apply multiple inheritances. Concatenate strings of classes X and Y and store it in the class Z. Show all the three strings. Use constructors and destructors.

(3) Write a program to calculate the salary of a medical representative based on the sales. Bonus and incentives to be offered to him will be based on total sales. If the sale exceeds Rs.1,50,000/- follow the particulars of Column (1) otherwise (2). Apply conditional constructor and destructor.

Column 1 Column 2
Basic = Rs. 3000 Basic = Rs. 3000
HRA = 20% of basic HRA = 20% of basic
DA = 110% of basic DA = 110% of basic
Conveyance = Rs.500 Conveyance = Rs.500
Incentives = 10% of sales Incentives = 5% of sales
Bonus = Rs. 1500 Bonus = Rs. 1000

(4) Write a program to calculate energy bill. Read the starting and ending meter reading. The charges are as given below:

No. of units consumed Rates in (Rs.)
200 - 500 4.50
100 - 2003.50
Less than 100 2.50

(5) The price of trophy depends on the type of material from which it is created. The following table gives the list of prizes. Write a program to input serial number of the material. In addition, display the material and its prize.

Serial no. Material Prize of trophy
01
02
03
04
05
Gold
Silver
Steel
Bronze
Pewter
Rs. 20,000/-
Rs. 9,500/-
Rs. 5,000/-
Rs. 500/-
Rs. 750/-

(6) A newspaper agent pays two variant rates for the delivery of newspapers. A delivery boy can earn Rs.2/- on a morning delivery but only Re. 1.50/- on an evening delivery. Boys are salaried either for a morning delivery or for an evening paper round but not for both. Write a program to read (input) the code for round (0 for morning and 1 for evening) and the number of total paper rounds in one week done by a boy and compute his earnings and display it.

(7) The postage for ordinary post is Rs. 2/- for the first 15 grams and Re. 1 for each additional 10 grams. Write a program to calculate the charge of the postage for a post weighing N grams. Read the weights of N packets and display the total amount of postage.

(8) Declare a class of vehicle. Derived classes are two-wheeler, three-wheeler, and four-wheeler. Display the properties of each type of vehicle using member functions of classes.

(9) Create classes country, state, city and village. Arrange these classes in hierarchical manner.

[D] Find bugs in the following programs.

(1)
       struct A  {     int x; };
       struct B  {     int y; };
       class C :  public A, B {};

       void main ( )
       {       C c;
             c.x=20; 
             c.y=30;
        } 


(2)
       struct A  { int x;  };
       struct B : A  { int y;  };
       struct C : A  { int z;  };
       struct D : B,C { int k; };
       void main ( )
       {       D d;

               d.x=20;

       }
(3) 
       struct  A
       {    int x;

       struct B { int y;   };    };

       struct C :   A::B,A    {    };

       void main ( )
       {       C c;
        c.x=40;
        c.y=20;
       }

(4)
       struct  A {   int x; };
       class  B :  A
       {       A a;   };

       void main ( )
       {       B b;          b.x=20;
        b.a.x=30;   }