Polymorphism and Types of Polymorphism

Polymorphism

 1. Introduction

Polymorphism is a mechanism in c++ that allows the same interface to invoke different functions or operators depending upon the type of objects using the interface. Let us assume an example of sending text message through a cell phone. Earlier the users are familiar with the system. Now to send multimedia messages if another interface would be there in the cell phone menu, the user will not feel the system much friendly as the previous one. Now if we put both the text message and multimedia message in the Message option, then the user can avail both the facilities through a single interface that is Message Box. This is what we do in polymorphism. The word polymorphism is derived from the Greek poly, meaning "many", and morph, which means "shape".

2. Types of Polymorphism

Polymorphism is broadly classified into two categories like compile time polymorphism and runtime polymorphism.

1446_Types of Polymorphism.jpg

2.1. Compile time polymorphism

In this category, the function or operator function is to be invoked is decided at the compile time. This is otherwise known as early binding or static binding or static linking. We have already implemented compile time polymorphism in chapters 2(Function overloading) and chapter 5(Operator overloading) earlier.

2.2. Run time polymorphism

Run time polymorphism is achieved through inheritance. In this category appropriate member function which is to be invoked is decided at the run time. This is otherwise known as late binding or dynamic binding. In c++, the run time polymorphism is achieved through virtual function, which we will discuss in detail in this chapter.

3. Pointer to derived class objects

Pointers can also be declared to point base as well as derived class objects. A base class pointer object is type compatible with its derived class objects. But the converse is not true, that means a derived class pointer object is compatible with its class objects only. This is illustrated in the following figure:

2264_Pointer to derived class objects.jpg

 

 

Consider that class B is derived from class A and the following declarations are made:

A  *aptr;

A   a_obj;

B   *bptr;

B   b_obj;

Following statements are considered as legal or illegal as per the above discussions.

aptr = &a_obj;             // legal

aptr = &b_obj;             // legal

bptr = &b_obj;             // legal

bptr = &a_obj;             // illegal because bptr is a derived class pointer and cannot    hold  the address of the base class object a_obj.

Remember that there is a problem with aptr that it can't access the public members of the derived class B. Using aptr we can access only those members which are inherited from the base class A and not the members of derived class B. The following program illustrates this:

Case 1

#include<iostream.h>

#include<constream.h>

class A

{

     public:

          int a;

          A()

          {

              a=10;

          }

          void display()

          {

              cout<<"In base class :"<<endl;

              cout<<"a = "<<a<<endl;

          }

};

class B:public A

{

     public:

          int b;

          B()

          {

              b=20;

          }

          void display()

          {

              cout<<"In derived class :"<<endl;

              cout<<"a = "<<a<<endl;

              cout<<"b = "<<b<<endl;

          }

};

main()

{

     clrscr();

     A *aptr;

     A a_obj;

     B b_obj;

     B *bptr;

     aptr=&a_obj;

     aptr->a=100;

     aptr->display();

     aptr=&b_obj;

     aptr->a=200;

     aptr->b=300;  // Error occurs due to this statement

     aptr->display();

     return(0);

}

Output:

The program displays the following error message during compilation:

Compiling D:\C__BOO~1\CHPATER7\PRG71.CPP:                                   

Error D:\C__BOO~1\CHPATER7\PRG71.CPP 44: 'b' is not a member of 'A'      

 

Case 2

Let us omit the error statement, recompile and observe the output of the above program in case 1 as:

 

#include<iostream.h>

#include<constream.h>

class A

{

     public:

          int a;

          A()

          {

              a=10;

          }

          void display()

          {

              cout<<"In base class :"<<endl;

              cout<<"a = "<<a<<endl;

          }

};

class B:public A

{

     public:

          int b;

          B()

          {

              b=20;

          }

          void display()

          {

              cout<<"In derived class :"<<endl;

              cout<<"a = "<<a<<endl;

              cout<<"b = "<<b<<endl;

          }

};

main()

{

     clrscr();

     A *aptr;

     A a_obj;

     B b_obj;

     B *bptr;

     aptr=&a_obj;

     aptr->a=100;

     aptr->display();

     aptr=&b_obj;

     aptr->a=200;

     aptr->display();

     return(0);

}

 

Output

In base class :

a = 100

In base class :

a = 200

Explanation:

Here we simply omit the statement  aptr->b=300 in case 1. Mark that any reference to the member by aptr will always access the base class member even if we assign the address of derived class object (& b_obj) to aptr. This is because class B access the same data member (a) which is also a data member of its base class A.

Case 3

#include<iostream.h>

#include<constream.h>

class A

{

     public:

          int a;

          A()

          {

              a=10;

          }

          void display()

          {

              cout<<"In base class :"<<endl;

              cout<<"a = "<<a<<endl;

          }

};

class B:public A

{

     public:

          int b;

          B()

          {

              b=20;

          }

          void display()

          {

              cout<<"In derived class :"<<endl;

              cout<<"a = "<<a<<endl;

              cout<<"b = "<<b<<endl;

          }

};

main()

{

     clrscr();

     A *aptr;

     A a_obj;

     B b_obj;

     B *bptr;

     aptr=&a_obj;

     aptr->a=100;

     aptr->display();

     ((B*)aptr)->b=300;

     ((B*)aptr)->display();

     return(0);

}

 

Output

In base class :

a = 100

In derived class :

a = 100

b = 300

Explanation

In this case we slightly change the statement as ((B*)aptr)->b=300

and ((B*)aptr)->display() to display the content of derived class object. It is clear that a base class pointer can point to any number of derived class objects, but cannot directly access the members defined by a derived class. 

 7.4 Virtual function

A virtual function is a member function preceded with the keyword virtual with its declaration, for e.g., virtual void display(), preferably in a base class. When a class that contains virtual function and is inherited, then the derived class redefines the virtual function to work out its own needs. In other words we can assume that it simply implements "one interface multiple forms" that underlies the basic phenomenon of polymorphism. Each redefinition of the virtual function by a derived class implements its operation as it relates specifically to the derived class only during inheritance is carried out.

Following are the few important clues to use virtual function in a program:

Make the function as virtual in the base class whose signature is same as derived class member functions.

For example:

 

class A

{

public:

      virtual void display()

      {

           cout<<"we are in class A";

      }

};

class B:public A

{

public:

      void display()

      {

           cout<<"we are in class B";

      }

};

The virtual member function is accessed through base class pointer using an arrow(→) operator instead of a dot(.) operator. This is so because the base class pointer can point to an object of its own class as well as derived class.

When the base class pointer point to derived class object that contains a virtual function, C++ determines which version of that function to be executed depending upon the type of object pointed to. This determination is done during runtime.

Program 1

Write a program to show the use of virtual function

#include<iostream.h>

#include<constream.h>

class btech

{

               protected:

                   int cgpa;

               public:

                   btech()

                   {

                        cgpa=10;

                   }

                   virtual void display()

                   {

                        cout<<"cgpa = "<<cgpa<<endl;

                   }

};

class mba:public btech

{

               protected:

                   int gpa;

               public:

                   mba()

 

                   {

                        gpa=100;    < ------------------- virtual function  display() redefined in deived class

                   }

                   void display()

                   {

                        cout<<"gpa = "<<gpa<<endl;

                   }

};

main()

{

               clrscr();

               btech *bptr,b1;

               mba m1;

               bptr=&b1;

               bptr->display();

               bptr=&m1;

               bptr->display();

               return(0);

}

 

Output

cgpa = 10

gpa = 100

 

Explanation

The above program is an illustration of virtual function or runtime polymorphism in case of single inheritance. Mark that inside btech class which is the base class, the member function display() is declared as virtual function. The same function is redefined by the class mba, which is the derived class. Mark that the keyword virtual is not mentioned. But it is not an error to include the keyword virtual with the function declaration in the derived class. The main() function contains three objects as:

Object                         Class type

bptr                              base class pointer

b1                                base class

m1                               derived class

Then bptr is assigned the address of b1 and the member function display() is invoked via bptr. As bptr contains the address of b1, so the exact version of member function display() in  class btech is invoked and displays the output cgpa=10 (initialized through constructor function btech()). Next the base class pointer bptr is assigned the address of m1 and again the corresponding display() function is invoked via bptr. So as bptr now contain the address of m1, the exact version of member function display() in class mba is invoked and displays the output gpa=100 (initialized through constructor function mba()).  

4.1 Rules for virtual function

  1. When virtual function in base class is created, there must be definition of the virtual function in the base class even if the base class version of the function is never actually called.
  1. Virtual function cannot be made as static.
  1. They can be  friend to another class
  1. They are always accessed using base class pointer object.
  1.  A base pointer can serve s pointer to derived object since it is type-compatible where as derived object pointer variable cannot serve as pointer to base objects.
  1. Its prototype in base class and derived class must be identical  for the virtual function to work properly.
  1. The class cannot have the virtual constructor, but can contain the virtual destructor.
  1. The virtual function should be declared in the public category of the class. However we can also define the virtual function outside the class, but for this we need to precede the keyword virtual with the declaration within the class.

For example

     class btech

     {

               protected:

                   int cgpa;

               public:

                   virtual void display();

    };

    void btech::display()

    {

               cout<<"cgpa = "<<cgpa<<endl;

    }

 

  1. We cannot use pointer arithmetic in case of base class pointer.

5. Pure virtual function

The virtual function contains no body or no function body is known as pure virtual function. A pure virtual function is otherwise called as do-nothing function or dummy function. The class which contain  pure virtual function  and contains no definition relative to the base class, such a class is called as an abstract class.

A pure virtual function can be declared in two ways:

Case 1

virtual void display()=0;

 

Case 2

virtual void display()

{

                        //Null body

}

In both the cases the function display() is called as pure virtual function.

Program 2

Write a program to show the use of pure virtual function

#include<iostream.h>

#include<constream.h>

class A

{

     protected:

          int a;

     public:

          A()

          {

              a=100;

          }

          virtual void display()=0;

};

class B:public A

{

     protected:

          int b;

     public:

          B()

          {

              b=200;

          }

          void display()

          {

              cout<<"a = "<<a<<endl;

              cout<<"b = "<<b<<endl;

          }

};

main()

{

     clrscr();

     A *aptr;

     B b1;

     aptr=&b1;

     aptr->display();

     return(0);

}

 

Output

a = 100

b = 200

Explanation

In the above program, the function display() is made as pure virtual function in class A. The base class pointer holds the address of derived class object b1 and invoke the function display() of the derived class B. If we try to invoke the display() function of class A, the compiler will generate an error message as we can't invoke the member function of the abstract class. The reader may check this as we do in program 1.

7.6.Virtul Destructor

It is known that the destructor member function is invoked to release the memory storage by the c++  compiler automatically. But the destructor member function of the derived class is not invoked to free the memory storage which was allocated by the constructor member function of the derived class. It is because the destructor member functions are  non virtual and the message will not reach the destructor  member functions during runtime. So the solution is to have a destructor member function as virtual in the base class. Virtual destructors are essential in  a program to free the memory space effectively during runtime polymorphism

The constructors cannot  be made as virtual because they need information about the exact type of the object to construct the memory for the objects .

The virtual destructor is declared with its normal declaration preceded by the keyword virtual as:

virtual ~classname();

Program 3

Write a program to show the working of virtual destructor

#include<iostream.h>

#include<constream.h>

class A

{

     public:

     A()

     {

          cout<<"Base class constructor"<<endl;

     }

     virtual ~A()

     {

          cout<<"Base class destructor"<<endl;

     }

};

class B:public A

{

     public:

     B()

     {

          cout<<"Derived class constructor"<<endl;

     }

     ~B()

     {

          cout<<"Derived class destructor"<<endl;

     }

};

main()

{

     clrscr();

     A *aptr;

     aptr=new B;

     delete(aptr);

     return(0);

} 

Output

Base class constructor

Derived class constructor

Derived class destructor

Base class destructor 

Explanation

The above program contains a virtual destructor in the base class A. The new operator allocates memory required for data members. When the object goes out of the scope it is deleted to release the memory space. When the base class pointer point to derived class object (aptr= new B), the virtual destructor release the memory dynamically for both the base and derived class. 

Summary

1 Polymorphism means many forms. Both the word "poly" and "morphs" are   derived from the Greek words. The combination of  these two words    is created as polymorphism

2 The information pertaining to various overloaded member function is to be given to the compiler while compiling .This is called s early binding  or static binding . Choosing the function at runtime is called as run-time or late dynamic binding .

3 Virtual functions of base class must be redefined in the derived class. The programmer can define  virtual function in  base class, and then can use the same function name in any derived class

4 The member function of the base class is rarely used for doing any operation., such functions are called s do-nothing functions or dummy functions or pure virtual function

5 All other derived classes without pure virtual functions are called as concrete classes

6 Abstract classes re like skeleton upon which new classes are designed to assemble well-designed class hierarchy. They are not used for object declaration.

7 Virtual function can be invoked using pointer or reference

8 We cannot construct s virtul constructor

9 We can define virtual destructor in a program to release the memory resource dynamically in run time.

How we help you? - C++ Assignment Help 24x7

We offer C++assignment help, C++ assignment writing help, programming assessments writing service, C++ tutors support, step by step solutions to Polymorphism problems, Polymorphism programming answers, C++ assignment experts help online. Our assignment help service is most popular and browsed all over the world for each grade level.

Why choose us - The first thing come in your mind that why choose us why not others what is special and different about us in comparison to other site. As we told you our team of expert, they are best in their field and we are always live to help you in your assignment which makes it special.

Key features of services are listed below:

  • Confidentiality of student private information
  • 100% unique and original solutions
  • Step by step explanations of problems
  • Minimum 4 minutes turnaround time - fast and reliable service
  • Secure payment options
  • On time delivery
  • Unlimited clarification till you are done
  • Guaranteed satisfaction
  • Affordable price to cover maximum number of students in service
  • Easy and powerful interface to track your order

assignment help

Popular Writing Services:-

  • Analog Electronics Looking for analog electronics assignment help - solutions to analog electronics problems, electronics engineering tutors service? Get tutor help for solutions.
  • Mechanical Engineering Seeking advice in mechanical engineering? looking for mechanical engineering assignment help and mechanical engineering assessments writing service? get help.
  • Extraction of Metals get extraction of metals assignment help online, assessment help and writing service from chemistry assignment experts.
  • Computational Physics Get Computational Physics Assignment Help Online, assessment help and Writing Service from Physics Assignment Experts.
  • Binomial Theorem get step by step solution to binomial theorem problems, binomial theorem assignment help online, math solutions from mathematics assignment experts.
  • Anatomy of Digital Computer Looking for anatomy of digital computer assignment help online, assessments writing service from computer science assignment experts.
  • Welfare economics get welfare economics assignment help online, welfare economics writing service, assessments writing help from economics assignment experts.
  • Electric Current Get Electric Current Assignment Help Online, assessment help and Writing Service from General Physics Assignment Experts.
Captcha

Get Academic Excellence with Best Skilled Tutor! Order Assignment Now! Submit Assignment