Tuesday 13 November 2012

Inheritance in C++


 Inheritance:

 In C++, inheritance is the mechanism by which one class can inherit the properties of another.
 When one class is inherited by another, the class that is inherited is called the base class. The inheriting class is called derived class.
 Base class is also known as parent class or old class. Derived class is also known as child class or new class.
 Remember constructor never inherits.
 Structure in C++ also supports inheritance.

Syntax for inheritance:

class base-name
{
  …
};
class derived-name : visibility mode base-name
{
 …
};

 Syntax covers two classes, one is base class and other is derived class.
 During derived class definition, notice a colon (:) followed by visibility mode and then comes base class name. This addition to derived class definition tells the compiler about linking between two classes.
 Members of base class now also consider members of derived class.
 Membership category for the base class members in derived class are defined by visibility mode.
 Visibility modes are private, protected and public.
 In class, when no visibility mode is mentioned, it is private by default.
 In structure, when no visibility mode is mentioned, it is public by default.

Visibility Modes:

 Whatever may the visibility mode, private members of base class never inherits.
 When visibility mode is private, all protected and public members of base class become private members of derived class.
 When visibility mode is protected, all protected and public members of base class become protected members of derived class.
 When visibility mode is public, all protected members of base class become protected members of derived class and all public members of base class become public members of derived class.



Advantages of inheritance:

 Reusability
 Saves time and efforts
 Increases program structure which results in greater reliability.
 It implements generalization and specialization

Types of inheritance:

There are five types of inheritance:

1) Single inheritance
When there is one parent class and one child class inheriting properties from base class, known as single inheritance.

Syntax:

class Base
{….};
class Derived: visibility mode Base
{….};

2) Multilevel inheritance
When a child class becomes parent of other class, it increases level of inheritance and known as multilevel inheritance.

Syntax

class A
{….};
class B: visibility-mode A
{….};
class C: visibility- mode B
{….};

3) Multiple inheritance
When a child class has more than one parent class, it is known as multiple inheritance.

Syntax

class A1
{….};
class A2
{….};
class B: visibility- mode A1, visibility-mode A2
{….};

4) Hierarchical inheritance
When a base class has more than one child classes, it is known as hierarchical inheritance.

Syntax

class A
{….};
class B1: visibility-mode A
{….};
class B2: visibility- mode A
{….};

5) Hybrid inheritance
A single structure of classes obtained from more than one type of inheritance is known as hybrid inheritance.

Syntax

class A
{….};
class B1: visibility-mode A
{….};
class B2: visibility- mode A
{….};
class C: visibility-mode B1, visibility-mode B2
{….};


Constructors in inheritance:
 Always remember constructor never inherits
 As long as no base class constructor takes any arguments, the derived class need not have a constructor function. However if any base class contains a constructor with one or more arguments, then it is mandatory for the derived class to have a constructor and pass the arguments to the base class constructors.
 When both the derived and base classes contain constructors, the base constructor is executed first and then the constructor in the derived class is executed.
 In multilevel inheritance the constructor will be executed in the order of inheritance. In case of multiple inheritance the base class are constructed in the order in which they appear in the declaration of the derived class.

Syntax:

Derived-constructor(arglist1,arglist2,…,arglist d) :
 base1(arglist1), base2(arglist2),…
{
  …
  …  //argument list d is used here(base constructor’s
  …            //definition
  …
}



Destructor in inheritance

Just like constructors destructors also non inheritable members. Their execution order is reverse the execution order of constructors. This means child class destructors executes first and followed by parent class destructors.


Function Overriding:

During inheritance when base class and derived class both shares a common function name in their respective class two situations encounters:
First scenario when a function in derived class has same name as of function in base class with same prototype. This is called function overriding.
Whenever this function s called using child class object child class version will be invoked.
To invoke base class version we need to specify class name and scope resolution operator.
Following example enlighten this fact.

#include<conio.h>
#include<iostream.h>
class Base
{
  public:
     void msg()
     {
          cout<<” Base Message”;
     }
};
class Derived : public Base
{
   public:
void msg()
     {
          cout<<” Derived Message”;
     }

};
void main()
{
  Derived O;
  O.msg(); //Derived class msg() executes
  O.Base::msg(); //Base class msg() executes
}


Function Hiding:

Second scenario is when base and derived class share same function name but different prototypes. In such case it can not be considered as function overloading as functions are in different scopes. Here, we say function hiding.

#include<conio.h>
#include<iostream.h>
class Base
{
  public:
     void msg(int k)
     {
          cout<<” Base Message”<<k;
     }
};
class Derived : public Base
{
   public:
void msg()
     {
          cout<<” Derived Message”;
     }

};
void main()
{
  Derived O;
  O.msg(); //Derived class msg() executes
  O.Base::msg(3); //Base class msg() executes
  O.msg(3); //error as derived msg() hides base msg(int)
}

Virtual base class:

A special scenario arises during hybrid inheritance. First to let us understand problem consider the following example

#include<conio.h>
#include<iostream.h>
class A
{
     public:
          void fun_a()
          {
              cout<<”Function of Class A”;
          }
};
class B1: public A
{
     public:
          void fun_b1()
          {
              cout<<”Function of Class B1”;
          }
};
class B2: public A
{
     public:
          void fun_b2()
          {
              cout<<”Function of Class B2”;
          }
};
class C: public B1, public B2
{
     public:
          void fun_c()
          {
              cout<<”Function of Class A”;
          }
};
void main()
{
   C O1;
   O1.fun_c(); //valid
   O1.fun_b1(); //valid as publicly inherited from base B1
   O1.fun_b2(); // valid as publicly inherited from base B2
   O1.fun_a(); //error: ambiguity between two copies of function in class C inherited twice // via class B1 and B2
}

Since function fun_a() of parent most class A is inherited twice in class C, first via class B1 and second via class B2. This makes two copies of the same function in child most class C and can not be resolved function call due to identical prototype. This leads to an ambiguity error.

Solution of the above problem is to make parent most class as virtual base class of class C. This means class A will now become virtually parent class of class C, instead of grant parent.

During definition of intermediate base classes B1 and B2, we mention keyword virtual to make parent class A virtual base class of child class of B1 and B2. Now only one copy of function fun_a() will be available for class C.

Following example illustrates syntactical part of virtual base class:
#include<conio.h>
#include<iostream.h>
class A
{
     public:
          void fun_a()
          {
              cout<<”Function of Class A”;
          }
};
class B1: virtual public A
{
     public:
          void fun_b1()
          {
              cout<<”Function of Class B1”;
          }
};
class B2: public virtual A
{
     public:
          void fun_b2()
          {
              cout<<”Function of Class B2”;
          }
};
class C: public B1, public B2
{
     public:
          void fun_c()
          {
              cout<<”Function of Class A”;
          }
};
void main()
{
   C O1;
   O1.fun_c(); //valid
   O1.fun_b1(); //valid as publicly inherited from base B1
   O1.fun_b2(); // valid as publicly inherited from base B2
   O1.fun_a(); // valid as only one copy of function in //class C
}

  

No comments:

Post a Comment