Wednesday, September 7, 2011

Virtual Function and overriding in C++ programs


Complete study of virtual function, pure virtual function, overriding of virtual function are discussed here.

So far we have seen function overloading and operator overloading. Those are examples of polymorphism. Now we will see another implementation of polymorphism through virtual function. Virtual means existing in effect but not in reality. A virtual function means that does not really exists but appears real to some part of a program. 

Suppose we have a number of objects of different classes but we want to put them all in a list and perform a particular operation on them using the same function. Suppose we have three different classes line, circle and triangle. Each class contains a function draw () . The function body statements of the function in different class must be different. Suppose draw () function of line class will draw line, draw () function of circle class will draw a circle and so on. If we want to draw a number of lines, circles and triangles on the screen, we have to create an array of pointers that will contain the addresses of the objects. Using loop and pointer we can access the address of the objects and by calling the draw () function, we will get different output on the screen. When the loop has accessed any object of line class, the draw () function will draw a line. Similar effects will be observed in case of circle or triangle class.

<h2>Program on virtual function</h2>

 #include< iostream.h>
#include< conio.h>
class abc
{
public:
void display()
{
cout<< "\nInside base class.";
}
};
class xyz:public abc
{
public:
void display()
{
cout<< "\nInside 1st derived class.";
}
};
class mn:public abc
{
public:
void display()
{
cout<< "\nInside 2nd derived class.";
}
};
void main()
{
clrscr();
xyz ob;
mn ob1;
abc *ptr;
ptr=&ob;
cout<< "\nFor object of 1st derived class."<< endl;
ptr->display();
ptr=&ob1;
cout<< "\nFor object of 2nd derived class."<< endl;
ptr->display();
getch();
}

In the above program we have two derived classes of base or super class abc. All the three classes have a function void display (). Inside  the void main () we have created one pointer of the 1st class and two different objects of the derived classes. Next we have assigned the address of the derived class objects on the pointer of the base class. This will not generate any error as address of any derived class can be hold by a pointer of it’s super class. After assigning the address of derived classes we called the display () function. But each time the base class version of display() function will be executed as the pointer type matches with the base class, ignoring the content of the pointer. So this will not provide the required facility as stated earlier (line ,circle and triangle class ).
Now we will make some change in our program. Use the keyword virtual before the function definition. 

#include< iostream.h>
#include< conio.h>
class abc
{
protected :
int a,b;
public:
void take()
{
cout<< "\nEnter two values:"<< endl;
cin>>a>>b;
}
virtual void display()
{
cout<< "\nInside base class.";
}
};
class xyz:public abc
{
public:
void display()
{
cout<< "\nSum for 1st derived class="<< a+b;
}
};
class mn:public abc
{
public:
void display()
{
cout<< "\nSum for 2nd derived class:"<< a+b;
}
};
void main()
{
clrscr();
xyz ob;
mn ob1;
abc *ptr;
ptr=&ob;
cout<< "\nFor object of 1st derived class."<< endl;
ptr->take();
ptr->display();
cout<< "\nFor object of 2nd derived class."<< endl;
ptr=&ob1;
ptr->take();
ptr->display();
getch();
}

In the above program the void display () function of the derived classes were executed. If we want to execute the base class version of the display () function, we have create an object of the base class also and assign it’s address on the base class pointer. Next call to the display () function will execute the base class void display () function.

In the above program we have overridden the void display () of the base class in it’s derived classes, but it was not compulsory. We can define a function name void display1 () in class xyz to perform the same work as void display () function. In such case also we can assign the address of xyz class object on the pointer of it’s base class ( here abc *ptr ). Then through the pointer we can call the void take () function for the xyz class object but can not call the void display1 () function through the base class pointer as the base class has no intimation regarding the void display1 () function. But in some cases function overriding may become compulsory. In such situation the base class function ( which must be overridden by it’s derived classes ) should be <b>pure virtual function</b>. A pure virtual function has no body The declaration of a pure virtual function is like :- virtual void display ()=0; In general a virtual function of any super class is never executed. When this is true , the body of the virtual function of a any super class can be removed using the notation =0. When a super class contains any pure virtual function, sub classes which inherits the super class must <b>override the pure virtual function</b>.

A class containing at least a pure virtual function is called abstract class. An abstract  class cannot create any object. But pointers can be declared of an abstract class. Other sub classes can inherits an abstract class. Abstract class should be used as base class.

#include< iostream.h>
#include< conio.h>
class abc
{
protected :
int a,b;
public:
void take()
{
cout<< "\nEnter two 'int' values::";
cin>>a>>b;
}
virtual void display()=0;
};
class xyz:public abc
{
public:
void display()
{
cout<< "\nSum for 1st derived class="<< a+b;
}
};
class mn:public abc
{
public:
void display()
{
cout<< "\nSum for 2nd derived class:"<< a+b;
}
};
void main()
{
clrscr();
xyz ob;
mn ob1;
abc *ptr;
ptr=&ob;
cout<< "\nFor object of 1st derived class."<< endl;
ptr->take();
ptr->display();
cout<< "\nFor object of 2nd derived class."<< endl;
ptr=&ob1;
ptr->take();
ptr->display();
getch();
}

No comments:

Post a Comment

Subscribe via email

Enter your email address:

Delivered by FeedBurner