Friday, 31 May 2013

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.

Consider the following example

#include<iostream.h>
class A
{
     private:
     int a;
     protected:
int b;
     public:
     void getdata()
     {
          cout<<”Enter two numbers”;
          cin>>a>>b;
}
     void showdata()
{
          cout<<”a=”<<a<<”b=”<<b;
}
};
class B : public A
{
     private:
     int m;
     protected:
     int n;
     public:
     void get()
     {
          cout<<”Enter two numbers”;
          cin>>m>>n;
     }
     void show()
     {
          cout<<”m=”<<m<<” n=”<<n;
     }
};
void main()
{
     B o1;
     o1.a=2;  //error: a is not a member of class B, private members never inherits
     o1.b=3;  //error: b is a protected member in class B, so can’t be access
     o1.m=4; //error: m is private member of class B, so can’t be access
     o1.n=5; // error: n is protected member of class B, so can’t be access
     o1.getdata(); //correct: as getdata() is a public member in class B
     o1.showdata(); //correct: as showdata() is a public member in class B
     o1.get();    //correct: as get() is a public member in class B
     o1.show(); //correct: as show() is a public member in class B
}
l  In this example, A is a base class and B is derived class.
l  Notice member variables and access specifiers for them. Also observe that the visibility mode is public during inheritance. This makes all protected members Protected in derived class and all public members become public members in derived class.
l  Some of the lines in above program will yield errors, so while executing remove these lines from main function. Read the comments to understand errors.
l  Whenever we want to extend class definition, we write a new class instead of writing members in the old class. This new class should be derived class of old one. Once we created object of child class it contains member variables of child class as well as parent class. This mechanism is good to support encapsulation. We should not create more than one object to store information of single object. By doing inheritance we can create a single object of child class to store information against variables of parent and child class.

Consider similar example but visibility mode is protected
#include<iostream.h>
class A
{
     private:
     int a;
     protected:
int b;
     public:
     void getdata()
     {
          cout<<”Enter two numbers”;
          cin>>a>>b;
}
     void showdata()
{
          cout<<”a=”<<a<<”b=”<<b;
}
};
class B : protected A
{
     private:
     int m;
     protected:
     int n;
     public:
     void get()
     {
          cout<<”Enter two numbers”;
          cin>>m>>n;
     }
     void show()
     {
          cout<<”m=”<<m<<” n=”<<n;
     }
};
void main()
{
  B o1;
  o1.a=2;  //error: a is not a member of class B, private members never inherits
     o1.b=3;  //error: b is a protected member in class B, so can’t be access
     o1.m=4; //error: m is private member of class B, so can’t be access
     o1.n=5; // error: n is protected member of class B, so can’t be access
     o1.getdata(); //error: getdata() is a protected member in class B
     o1.showdata(); //error: showdata() is a protected member in class B
     o1.get();    //correct: as get() is a public member in class B
     o1.show(); //correct: as show() is a public member in class B
}

Consider another similar example for visibility mode private

#include<iostream.h>
class A
{
     private:
     int a;
     protected:
int b;
     public:
     void getdata()
     {
          cout<<”Enter two numbers”;
          cin>>a>>b;
}
     void showdata()
{
          cout<<”a=”<<a<<”b=”<<b;
}
};
class B :  private A
{
     private:
     int m;
     protected:
     int n;
     public:
     void get()
     {
          cout<<”Enter two numbers”;
          cin>>m>>n;
     }
     void show()
     {
          cout<<”m=”<<m<<” n=”<<n;
     }
};
void main()
{
   B o1;
     o1.a=2;  //error: a is not a member of class B, private members never inherits
     o1.b=3;  //error: b is a private member in class B, so can’t be access
       o1.m=4; //error: m is private member of class B, so can’t be access
       o1.n=5; // error: n is protected member of class B, so can’t be access
     o1.getdata(); //correct: getdata() is a private member in class B
     o1.showdata(); //correct: showdata() is a private member in class B
      o1.get();    //correct: as get() is a public member in class B
      o1.show(); //correct: as show() is a public member in class B
}

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
l  Always remember constructor never inherits
l  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.
l  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.
l  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
  …
}

Consider the following example to implement constructors in inheritance

#include<iostream.h>
#include<conio.h>
class A
{
     private:
          int a;
     public:
          A()
          {
              cout<<”\nBase Class Constructor”;
              a=0;
          }
          void showa()
          {
              cout<<”\na=”<<a;
          }
};
class B : public A
{
     private:
          int b;
     public:
          B():A()
{
     cout<<”\nChild Class Constructor”;
     b=0;
          }
          void showb()
          {
              cout<<”\nb=”<<b;
          }
};
void main()
{
     B obj;
     obj.showa();
     obj.showb();
     getch();
}

Explanation:
l  Constructor of child class is invoked as soon as we create object of child class B. But important thing to notice that child class constructor invite parent class constructor to run parent class constructor before child class constructor.
l  So the output of the above program is
Base Class Constructor
Child Class Constructor
a=0
b=0
l  Notice the way child constructor call base class constructor. It is child class constructor then colon (:) and followed by base class constructor call.
l  If we have base class constructor with arguments then it is the duty of child class constructor to pass arguments.
l  If there is no constructor in base class then child class constructor calls implicit constructor of base class.
l  If there is no constructor in child class and base class contain default constructor or constructor with no argument then implicit constructor of child class would call constructor of parent class.
l  If there is a parameterized constructor in parent class then it is must to define a constructor in child class who invokes parent class constructor by passing correct number of arguments
l  We can say execution order of constructor is the order of inheritance that is from parent most class to child class


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
}


l  The keyword virtual and visibility mode can appear in either order.
l  Now Class A becomes virtually base class of class C

Type Conversion in C++


Meaning of Type Conversion

  • Consider the following segment of code:
void main()
{
   int x;
   float y=3.25;
   x=y;
   …
}

  • Here, x and y are of different types but during assignment of content of y into x, type of the content of y automatically converted into an int type value.
  • We can say compiler supports automatic type conversion for primitive data types.
  • The problem arises when at least one of the variables is of user defined data type.
  • We categorized the situation into three branches:
    • Basic type to class type
    • Class type to basic type
    • One class type to another class type

Basic type to Class type

#include<iostream.h>
class complex
{
     private:
            int a,b;
     public:
            complex() { } //default constructor
            complex(int x) {a=x; b=x; } //used in type conversion
            void showdata();        
            void getdata();
};
void complex:: getdata()
{
            cout<<”Enter two numbers”;
            cin>>a>>b;
}
void complex:: showdata()
{   cout<<”a=”<<a<<”b=”<<b;  }
void main()
{
  complex c1;
  c1.showdata();
  int k=5;
  c1=k;  //basic type to class type
  c1.showdata();
}

  • Here, notice the line c1=k; in function main(). The value of k which is an integer, assigned to an object c1 of type complex. This leads to an error due to type difference.
  • The problem can be solved with constructor. We studied earlier that a constructor is called automatically when an object is created. In addition to this fact, constructor also called when we try to assign a value other than object’s type.
  • So we need to define a constructor which takes one argument of type int.
  • Observe that we have created two constructors in complex class. One is default constructor (called during object creation) and another is parameterized constructor ( called during type conversion)
  • The value of k is passed to the constructor which is received by variable x, further this value is transferred to variables a and b.

Class type to basic type

#include<iostream.h>
class complex
{
     private:
            int a,b;
     public:
            void getdata();
            void showdata();        
            operator int()
            { return(a+b); }
};
void complex:: getdata()
{
            cout<<”Enter two numbers”;
            cin>>a>>b;
}
void complex:: showdata()
{   cout<<”a=”<<a<<”b=”<<b;  }
void main()
{
  complex c1;
  c1.getdata();
  c1.showdata();
  int k;
  k=c1;  //class type to basic type
  cout<<”k=”<<k;
}

  • Here, object c1 of class complex is assigned to an int type variable k.
  • Notice the line k=c1; c1 has to convert into an int type to store in variable k.
  • This can not be done with the help of constructor as object is on the right side of assignment operator.
  • This problem can be solved with casting operator.
  • Observe casting operator in class complex. Definition starts from keyword operator followed by data type (it should be according to the type of variable in the left side of assignment, in our example it is int as k=c1) and again followed by empty parenthesis. Body of casting operator is similar to body of any function.
  •  Since k can contain only one value of type int, there should be some mechanism or logic (according to the programming need) to manipulate content of object c1 into a single value. Here we add a and b, result is then returned, which is received by variable k in function main.

One class type to another class type

#include<iostream.h>
class item
{
    int m,n;
  public:
    void showdata()
    { cout<<”m=”<<m<<”n=”<<n; }
     void getm(int x) { m=x; }
     void getn (int y)  { n=y; }
  };
class complex
{
     private:
            int a,b;
     public:
            void showdata();        
{   cout<<”a=”<<a<<”b=”<<b;  }
            void complex:: getdata()
{
              cout<<”Enter two numbers”;
              cin>>a>>b;
}
operator item()
{
  item i;
  i.getm(a);
  i.getn(b);
  return(i);
};
void main()
{
  complex c1;
  item i1;
  c1.getdata();
  c1.showdata();
  i1=c1;   //One class type to another class type
  i1.showdata();
}

  • If we have to convert one class type data into another class type, then this can be done either with the help of constructors or operator overloading.
  • In the above example we are using casting operator.
  • Casting operator in class complex is called for object c1 (see line i1=c1 in main)
  • We have created an object  i of type item in casting operator, set values of variables of object i. Lastly we returned object i, which is then received by i1 in function main. 

Friend Function in C++


Introduction to friend function

  • Member function can access private members of the class along with other members of the same class.
  • Non member functions can not access private members of the class.
  • Friend functions can access private members of the class along with other members of the class though it is not a member function.
  • Friend function is a special non member function whose declaration part should be in the class body preceded by keyword friend. This makes clear to the compiler that this function is friend to the class in which it is declared.
  • Definition part should be kept outside the class body.
  • Remember, not to put membership label while defining friend function as it is not a member function.

Consider the following example:
#include<iostream.h>
class complex
{
     private:
     int a,b;
     public:
     void getdata();
     void showdata();  
     friend void dost();
};
void complex:: getdata()
{
     cout<<”Enter two numbers”;
     cin>>a>>b;
}
void complex:: showdata()
{
     cout<<”a=”<<a<<”b=”<<b;
}
void complex::dost()
{
     cout<<a<<b;
}
void main()
{
  complex c1;
  c1.getdata();
  c1.dost();
  c1.showdata();
}

l  Don’t trust on the above code. Above program is to make you understand about few of the common mistakes.
l  First of all object cannot call friend function as dost() is not a member function. So dost() should be called independently like any other non member function.
l  Second mistake is during definition of function dost(). Remember membership label should be used for member functions.
l  Third mistake is, friend function can access private members of the class but not independently (without using object and dot operator).
l  For any member function object is required to invoke it and the variables used in member functions are of the object who invokes the member function.
l  Here, dost() is not a member, hence can not be called by any object then whose variable a and b are being used by function dost(). This forces the programmer to pass object during function call so that friend function can access object members.
l  The following example is correction in the previous program:

#include<iostream.h>
class complex
{
     private:
     int a,b;
     public:
     void getdata();
     void showdata();  
     friend void dost(complex);
};
void complex:: getdata()
{
     cout<<”Enter two numbers”;
     cin>>a>>b;
}
void complex:: showdata()
{
     cout<<”a=”<<a<<”b=”<<b;
}
void dost(complex c)
{
     cout<<c.a<<c.b;
}
void main()
{
  complex c1;
  c1.getdata();
  dost(c1);
  c1.showdata();
}


Defining operator as a friend function
#include<iostream.h>
class complex
{
     private:
     int a,b;
     public:
     void getdata();
     void showdata();  
     friend complex operator +(complex, complex);
};
complex operator +(complex d1, complex d2)
{
  complex temp;
  temp.a=d1.a+d2.a;
  temp.b=d1.b+d2.b;
  return(temp);
}
void complex:: getdata()
{
     cout<<”Enter two numbers”;
     cin>>a>>b;
}
void complex:: showdata()
{
     cout<<”a=”<<a<<”b=”<<b;
}
void main()
{
  complex c1,c2,c3;
  c1.getdata();
  c2.getdata();
  c3=c1+c2; 
  c3.showdata();
}
l  Observe main() function, specially the line c3=c1+c2;. Calling convention is same as we did in operator overloading without friend function. But the interpretation is not same.
l  Here, the valid interpretation is, operator ‘+’ is called independently (as it is non member) and c1 and c2 objects are passed.
l  These objects are then received in d1 and d2 (see definition part of ‘+’)
l  Object temp is used to temporary hold the addition result and return back to main() where the value of temp copied into object c3.

Overloading insertion (<<) and extraction (>>) operator

#include<iostream.h>
class complex
{
     private:
     int a,b;
     public:
     void getdata();
     void showdata();  
     friend ostream & operator <<(ostream &, complex);
            friend istream & operator >>( istream &,complex &);
};
ostream & operator <<(ostream &dout, complex c)
{
  dout<<c.a<<” “<<c.b;
  return(dout);
}
istream  & operator >>(istream &din, complex &c)
{
  din>>c.a>>c.b;
  return(din);
}
void complex:: getdata()
{
     cout<<”Enter two numbers”;
     cin>>a>>b;
}
void complex:: showdata()
{
     cout<<”a=”<<a<<”b=”<<b;
}
void main()
{
  complex c1,c2;
  cout<<”Enter real and img part: “;
  cin>>c1;
  cout<<”Enter real and img part: ”;
  cin>>c2;
  cout<<”Values of object c1:”
  cout<<c1;
  cout<<”Values of object c2:”
  cout<<c2; 
}

l  We cannot create object of class istream and ostream but we can make references of these classes (as we do in friend functions).
l  Here we overload two operators inserter (<<) and extractor (>>).
l  Notice the line cin>>c1 in main(), operator  >> is called and references of cin and c1 are passed. This is then received in reference object din and reference variable c.
l  Similarly, notice the line cout<<c1, operator << is called and reference of cout and c1 are passed. This is then received in reference object dout and variable c.
l  Coding inside inserter and extractor are self explanatory.