Virtual functions play an important role in object oriented programming. Ordinary functions use the concept of early binding. However virtual functions help in late binding. The concept of pointers playa vital role in Virtual functions.
Pointer to a class
Consider a class Person
class Person { member data void input() // member function {} };
A pointer to the class Person is defined as follows:
Person *o1; o1->input();
o1 is a pointer to the class Person and the second statement is used for executing the member function input(). Now instead of a dot operator, -> symbol is used. Consider an example in which Teacher is a derived class of the base class Person and has a member function of the same name in both classes as shown below.
class Person { member data void input() // member function {} }; class Teacher: public Person { member data void input() // member function {} };
and the main function contains the following statements
Person *o1; ol=&Teacher; ol->input();
Although o1 has been given the address of Teacher, the compiler will always invoke the member function of the base class (Person class). This is because binding takes place at the time of compilation when the contents of the pointer are not known. This is known as early binding.
Following is a program to illustrate the anomalies which occur due to early binding.
Example
consumer is a base class having member data name, code and telephone number( tel) and member functions getdata() and display(). transaction is a derived class having member data quantity( qty), price and total and member functions with the same names as the base class.
#include #include const int size=10; class consumer { protected: char name[size]; int code; char tel[size]; public: consumer() { strcpy(name," "); code=0; strcpy(tel," "); } void getdata() { cout<<" enter name"; cin>>name; cout<<"enter code "; cin>>code; cout<<"enter telephone number"; cin>>tel; } void display() { cout<<"\nname "<<name<<endl; cout<<" code" <<code<<endl; cout<<"telephone "<<tel<<endl; } }; class transaction: public consumer { protected: int qty; float price; float total; public: transaction() { qty=0; price=0; total=0; } void getdata() { consumer::getdata(); cout<<"enter quantity ";cin>>qty; cout<<"enter price ";cin>>price; } void display() { consumer::display(); cout<<"quantity "<<qty<<endl; cout<<"price "<<price<<endl; cout<<"\ntotal price "<<qty*price<<endl; } }; void main( ) { consumer* o1; transaction o2; o1=&o2; o1->getdata(); o1->display(); }
o1 is a pointer to the base class customer. o2 is a derived class transaction object and its address is passed on to pointer o1. When the overriding member functions getdata() and display() are invoked by the object (of pointer type) o1, the base class functions are invoked and not the derived class functions.
On the execution of the above program, the following screen is displayed and the data is entered.
enter name Sharma
enter code o1
enter telephone number 678234
Output
name Sharma
code 1
telephone 678234
In order to implement late binding, the concept of virtual functions have to be employed.