You are on page 1of 14

MODULE 3

VIRTUAL FUNCTIONS AND POLYMORPHISM


 Polymorphism: - One name, multiple forms
 Overloaded member functions are selected for invoking by matching arguments, both type
and number. This information is known to the compiler at the compile time and therefore,
compiler is able to select the appropriate function for a particular call at the time of
compilation. This is called “early binding or static binding”.

Ambiguity Resolution in Inheritance


Example:
class A
{
public:
void display()
{
cout << “\n In A”;

E S . I N
NOT
}
};

class B : public A
{
KTU
public:
void display()
{
cout << “\n In B”;
}
};
main()
{
B b;
b.display(); //invokes function in B
b.A : : display(); //invokes function in A
b.B : : display(); //invokes function in B
}

Output:
In B
In A
In B

Downloaded from Ktunotes.in


 Let there is more than one function in base class and derived class such that some functions
of derived class have the same name, but different prototype as that of the functions in base
class. In such a case the function will be overloaded.
 But if prototypes are same, the function is not overloaded, but gets override.
 In such situations we may use the class resolution operator ( : : ) to specify class while
invoking the functions with derived class objects.
 It would be nice if the appropriate member function could be selected while the program is
running. It is known as “runtime polymorphis m”.
 C++ supports a mechanism known as “virtual function” to achieve runtime polymorphism.

Polymorphism

Runtime Polymorphism Compile time Polymorphism

E S . I N

Virtual function

KTU NOT
Function Overloading Operator Overloading

Since function is linked with a particular class much later after the compilation, this process
is termed as “late binding” or “dynamic binding”.

Pointe rs
The variable that stores the address of another variable is called a pointer.

Downloaded from Ktunotes.in


Indirection Operation (*)
It is a unary operator whose operand must be a pointer value. The result is an expression
that can be used to access the pointed variable for the purpose of inspection or alteration. To
access a through the pointer p, we simply code *p.

Example:
We can change the content of a using any one of the following method:
a = a + 1;
*p = *p + 1;

Address Operator (&)


It is a unary operator that returns the memory address of its operand. For example, if var
is an integer variable, then &var is its address.

Pointe r Declaration and Definition


E S . I N
Syntax for pointer declaration:

KTU
Initialization of pointer variable: NOT datatype * pointername;
int x;
int* p = &x;

Example:
#include < iostream >
using namespace std;
main()
{
int a;
int * p;
a = 14;
p = &a;
cout << “Content of a = ” << a << endl;
cout << “Address of a = ” << &a << endl;
cout << “Content of a = ” << *p << endl;
cout << “Address of a = ” << p << endl;
}

Downloaded from Ktunotes.in


Output:
Content of a = 14
Address of a = 0x00135760
Content of a = 14
Address of a = 0x00135760

POINTERS TO OBJECT
 A pointer can point to an object created by a class.

Example:
item x;
where item is a class and x is an object defined to be of type item. Similarly we can define a
pointer it_ptr of type ite m as follows:
item *it_ptr;

 Object pointers are useful in creating objects at run time. We can also use an object pointer to

E S . I N
access the public members of an object. Consider the class item defined as follows:

class item
KTU NOT
{
int code;
float price;
public:
void getdata(int a, float b)
{
code = a;
price = b;
}
void show()
{
cout << “code = “ << code << “price = “<< price;
}
};
main()
{
item x;
These statements are equivalent to:
item *ptr = &x;
ptr -> getdata(5, 500.75); x.getdata(5, 500.75);
ptr -> show();
x.show();

Downloaded from Ktunotes.in


}

Ouput:
code = 5 price = 500.75

 We can also create object using pointers and “new” operator as follows.
item *ptr = new item ;
This statement allocates enough memory for the data members in the object structure and
assigns the address of the memory space to ptr. Then ptr can be used to refer to the members as
shown below:
ptr -> show();
Note: If a class has a constructor with arguments and does not include an empty constructor,
then we must supply the arguments when the object is created.
 We can also create an array of objects using pointers as given below,
item *ptr = new item[10];

S . I N
This statement creates memory space for an array of 10 objects of item.
E
class item
{ KTU NOT
int code;
float price;
public:
void getdata(int a, float b)
{
code = a;
price = b;
}
void show()
{
cout << “code = “ << code << “price = “<< price;
}
};
main()
{
item *ptr = new item[2]; // This statement creates a pointer to an array of objects.
ptr -> getdata(5, 500); // the pointer ptr points to the first element in the array of objects
ptr ++; // the pointer is incremented. i.e. ptr now points to the next(2nd) object in the array
ptr -> getdata(6, 600); // pointer ptr points to the second element in the array of objects

Downloaded from Ktunotes.in


ptr -> show();
ptr --;
ptr -> show();// ptr points to first element
}

Ouput:
code = 5 price = 500
code = 6 price = 600

“this” Pointer
 C++ uses a keyword called “this” to represent an object that invokes a member function. this
is a pointer that points to the object for which this function was called.

Example:
The function call A.max() will set the pointer this to the address of the object A.

 The starting address is the same as the address of first variable in the class structure.

E S . I N
NOT
Example:
class ABC
{
private:
KTU
int a;
};

The variable “a” can be used directly inside a member function like:
a = 123;
The statement: this -> a = 123; is equivalent to the above statement.

 One important application of the pointer “this” is to return the object it points to.
return *this; //This statement returns the object that invoked the function.

Example:
class person
{
string name;
int age;

Downloaded from Ktunotes.in


public:
person(string n, int a)
{
name = n;
age = a;
}
person & greater(person &x)
{
if (x.age >= age)
return x;
else
return *this;
}
void display()
{
cout << “name = ” << name << “, age = ” << age;
}
};
main()
{
person p1(“Abc”, 70);
person p2 (“Xyz”, 10);
person p = p1.greater(p2);

E S . I N
NOT
cout << “Elder: \n”;
p.display();
}

Ouput:
KTU
Elder:
name = Abc, age = 70

 The dereference operator *produces the contents at the address contained I the pointer.

Pointers to Derived Classes


 We can use pointers not only to the base object but also to the objects of derived classes.
 A single pointer variable can be made to point to objects belonging to different classes.

Example:
Let “B” be the base class and “D” be the derived class.
B *cptr; // a pointer to class B type variable
B b; // base object

Downloaded from Ktunotes.in


D d; // derived object
cptr = &b; // cptr points to object b
We can make cptr to point to the object d as shown below:
cptr = &d; // cptr points to object d

 This is valid in C++, if D is derived from B.


 Using cptr, we can access only those members which are inherited from B and not the
members that originally belong to D.
 In case a member of the class D has the same name as one of the member of B, then any
reference to that member by cptr will always access the base class member.

Example:
class BC
{
public:
int b;
void show()
E S . I N
NOT
{
cout << “b = ” << b;

};
}

class DC : public BC
KTU
{
public:
int d;
void show()
{
cout << “b = ” << b << “d = ” << d;
}
};
int main()
{
BC *bptr; // base pointer
BC base;
bptr = &base; // assigns address of base class object to base pointer
bptr -> b = 100;
bptr -> show();
DC derived;
bptr = &derived // assigns address of derived class object to base pointer
bptr -> b = 200;

Downloaded from Ktunotes.in


bptr -> show();
DC *dptr = &derived;
dptr -> d = 300;
dptr -> show();
}
Ouput:
b = 100
b = 200
b = 200 d = 300

 bptr -> show() always calls the function BC :: show()


 A base pointer can be made to point to any number of derived objects; it cannot directly
access the members of derived class.

VIRTUAL FUNCTION
 In the above example we use the pointer to base class to refer to all the derived objects. But a
base pointer, even when it is made to contain the address of a derived class, always executes


the function in the base class.

E S . I N
NOT
Compiler simply ignores the contents of the pointer and chooses the member function that

KTU
matches the type of the pointer.
 In such a situation polymorphism is achieved using “virtual functions”
 When we use the same function name in both base and derived classes, the function in base
class is declared as virtual, using the keyword “virtual”.
 When function is made “virtual” then C++ determines which function to use at runtime based
on the type of object pointed to by the base pointer, rather than the type of pointer.

Example:
class Base
{
public:
void display()
{
cout << “Display function of Base”;
}
virtual void show()
{
cout << “Show function of Base”;

Downloaded from Ktunotes.in


}
};
class Base
{
public:
void display()
{
cout << “Display function of Derived”;
}
void show()
{
cout << “Show function of Derived”;
}
};
main()
{
Base B;
Derived D;
Base *bptr;
bptr = &B;
bptr -> display();
bptr -> show();
bptr = &D;

E S . I N
NOT
bptr -> display();
bptr ->show();
}

Output:
KTU
Display function of Base
Show function of Base
Display function of Base
Display function of Derived

Rules for Virtual Function


 Virtual function must be member of some class.
 Virtual function cannot be static member.
 Virtual function is accessed by using object pointer.
 It can be a friend of others.
 A virtual function in a base class must be defined, even though it may not be used.
 Prototypes of base class version of a virtual function and the entire derived class version
must be identical. If two functions with same name have different prototypes, C++ considers
them as overloaded functions, and virtual function mechanism is ignored.

Downloaded from Ktunotes.in


 We cannot have virtual constructor, but we can have virtual destructors.
 If a virtual function is defined in the base class, it need not be necessarily redefined in the
derived class; in such cases calls will invoke the base function.

PURE VIRTUAL FUNCTION


 Pure Virtual Function is a “do – nothing function” defined as:
virtual void display() = 0;
 Pure Virtual Function is function declared in a base class that has no definition relative to the
base class. In such cases, the compiler requires each derived class to either define the
function or redeclare it as a pure virtual function.
 Class containing pure virtual functions cannot be used to declare any object of its own. Such
a class is called “Abstract Base Class”.
 Objective of abstract base class is to provide some traits to the derived classes and to create a
base pointer required for achieving runtime polymorphism.

E S . I N
NOT
VIRTUAL CONSTRUCTORS AND VIRTUAL DESTRUCTORS

KTU
We can have virtual destructors but not virtual constructors.

Example:
class base
{
public:
base()
{
cout << “Base Constructor”;
}
~base()
{
cout << “Base Destructor”;
}
};
class derived : public base
{
public:
derived ()
{

Downloaded from Ktunotes.in


cout << “Derived Constructor”;
}
~derived ()
{
cout << “Derived Destructor”;
}
};
main()
{
base * baseobj = new derived();
delete baseobj;
}

Output:
Base Constructor
Derived Constructor
Base Destructor

 Here, since the destructor in the base class is not virtual, the destructor which is called will
only be base : : ~base().

E S . I N
To call the destructor function of the derived class we must make the destructor function in

NOT
base class as virtual.

KTU
 Declaring virtual destructors in classes that have virtual functions causes the compiler to call
destructors for each class from which the object inherits.

Program to implement Virtual Destructor:


class base
{
public:
base()
{
cout << “Base Constructor”;
}
virtual ~base()
{
cout << “Base Destructor”;
}
};
class derived : public base
{
public:
derived ()

Downloaded from Ktunotes.in


{
cout << “Derived Constructor”;
}
~derived ()
{
cout << “Derived Destructor”;
}
};
main()
{
base * baseobj = new derived();
delete baseobj;
}

Output:
Base Constructor
Derived Constructor
Derived Destructor

E S . I N
KTU NOT

Downloaded from Ktunotes.in

You might also like