0% found this document useful (0 votes)
2 views

CH7

The document explains polymorphism in programming, highlighting compile-time and run-time polymorphism, with examples of function overloading and overriding. It discusses the importance of virtual functions for enabling dynamic binding, allowing derived class functions to be invoked through base class pointers. Additionally, it covers pure virtual functions, abstract classes, virtual destructors, and run-time type information (RTTI) using dynamic_cast and typeid operators.

Uploaded by

herohero9851
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

CH7

The document explains polymorphism in programming, highlighting compile-time and run-time polymorphism, with examples of function overloading and overriding. It discusses the importance of virtual functions for enabling dynamic binding, allowing derived class functions to be invoked through base class pointers. Additionally, it covers pure virtual functions, abstract classes, virtual destructors, and run-time type information (RTTI) using dynamic_cast and typeid operators.

Uploaded by

herohero9851
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Polymorphism and

virtual functions
Polymorphism 2

 Having same name but different functionality


 Two categories:
 1.Compile time polymorphism
 Early or static binding
 Static polymorphism refers to the binding of functions on the basis
of their signature (number, type and sequence of parameters).
 Itis also called early binding because the calls are already bound
to the proper type of functions during the compilation of the
program depending upon type and sequence of parameters.
 E.g. Function overloading, operator overloading
Polymorphism 3

 2. Run time polymorphism


 Late or dynamic binding
A function is said to exhibit dynamic polymorphism if it exists in
various forms, and the resolution to different function calls are
made dynamically during execution time.
 This feature makes the program more flexible as a function can
be called, depending on the context.
 E.g. Function overriding using Virtual Functions
Pointers to the derived class 4

 We can create pointer type object of both base class as well as


derived class pointer.
 The pointer object of the derived class will always be type
compatible with base class pointer.
 Base class pointer can invoke member function
base *b1;
that is defined in base class only. base b2;
 If member functions are defined in derived class derived d;
b1=&b2;
only, then these functions cannot be accessed b1->display( );
b1=&d;
from base pointer. b1->display( );
main()
class B {
{
5
B b, *bp[2];
public: D d;
void show() bp[0]=&b;

{ cout<<"I am in base show"<<endl; } bp[0] ->show();


bp[1] =&d;
};
bp[1] ->show(); // invokes overridden function of base class only
class D:public B
// bp[1] ->display(); cannot be invoked
{
D *dp;
public:
dp=&d;
void show() dp -> display();
{ cout<<"I am in derived show"<<endl; } }
void display()
{ cout<<"I am in derived only"; } Output:

}; I am in base show
I am in base show
I am in derived only
Need of virtual function 6

 If we use base class pointer to access the derived class member,


then the function overriding cannot be done.
 That is, if the base class and derived class have same function ,
then only base class member function can be accessed through that
pointer even if we assign the address of derived class to the base
class pointer.
 Here, the function is associated only to the type of pointer but not the
content of the pointer.
 If we want to invoke the function depending on object that is being
pointed by the pointer type of object, we need to use virtual function.
Virtual function 7

 Virtual function is a non-static member function that is declared


within a base class and redefined by a derived class
 Determines which function to execute during runtime based on type
of object pointed by base pointer rather than type of pointer.
 To create a virtual function, precede the function's declaration in
base class by keyword “virtual”
 For every base class that has one or more virtual functions, a table of
function addresses is created during run time.
 This table of function addresses is called the virtual table that contains
the address of each and every virtual function that has been defined
in the corresponding class.
main()
class B {
{ B b, *bp[2]; 8
public: D d;
virtual void show() bp[0]=&b;
bp[1] =&d;
{ cout<<"I am in base show"<<endl; }
void display() bp[0] ->display();
{ cout<<"I am in base display"<<endl; } bp[1] ->display();
};
class D:public B bp[0] ->show();
bp[1] ->show();
{
}
public:
void show() Output:
{ cout<<"I am in derived show"<<endl; } I am in base display

void display() I am in base display


I am in base show
{ cout<<"I am in derived display"<<endl; }
I am in derived show
};
main()
“Virtual”ness is inherited
{
class B B b, *bp[3]; 9
{ public: D1 d;
virtual void show() D2 e;

{ cout<<"I am in base show"<<endl; }


bp[0]=&b;
};
bp[1] =&d;
class D1:public B bp[2] =&e;
{ public:
void show() bp[0] ->show();
bp[1] ->show();
{ cout<<"I am in derived1 show"<<endl; }
bp[2] ->show();
};
}
class D2:public D1
{ public: Output:
void show() I am in base show
I am in derived1 show
{ cout<<"I am in derived2 show"<<endl; }
I am in derived2 show
};
Pure Virtual function and abstract 10
class/abstract base class
 Virtual function without its definition in base class is known as
“Pure Virtual Function”.
 virtual void show() = 0;
 Do-nothing function
 The base class containing pure virtual function cannot be
used to create objects, hence it is called abstract class or
abstract base class.
 Abstract class is used to create base class pointers only for
achieving runtime polymorphism.
class dimension class rectangle:public dimension
{ { 11
protected: public:
int l,b; rectangle(int x , int y):dimension(x,y){ }
public: void area()
dimension(int x, int y): l(x),b(y){ } { cout<<"Area of rectangle is "<<l*b<<endl; }
virtual void area()=0; };
};
main()
class square:public dimension {
{ square s(5);
public: rectangle r(10,2);
square(int x):dimension(x,x){ } dimension *bp[2]={&s, &r};
void area() bp[0] ->area();
{ cout<<"Area of square is "<<l*l<<endl; } bp[1] ->area();
}; }
Virtual Destructor 12

 Destructors are invoked automatically to free memory


space
 But in derived classes, it is not invoked automatically
because destructors that are non-virtual will not get
message under late binding
 So, the destructors are made virtual to free space under late
binding method.
 But the constructors cannot be virtual because virtual table
would not have been created during object creation so
that it would not have anywhere to look up to.
class base main()
{ public: { 13
virtual void show() base *bp = new base;
{ cout<<"I am in base show"<<endl; } bp ->show();
virtual ~base()
{ cout<<"I am in base destructor"<<endl; } bp=new derived;
}; bp ->show();
class derived : public base delete bp;
{ public: }
void show()
{ cout<<"I am in derived show"<<endl; }
~derived() Output:
{ cout<<"I am in derived destructor"<<endl; } I am in base show
}; I am in derived show
I am in derived destructor
I am in base destructor
Run Time Type Information(RTTI) 14

 Provides information of object during runtime


 Available only for polymorphic class (class with virtual
function).
 The “dynamic_cast” and “typeid” operators are used for
these purpose
 Must include <typeinfo>header file for typeid operator
dynamic_cast operator 15

 The dynamic_cast operator is intended to be the most heavily


used RTTI component.
 It doesn't answer the question of what type of object a pointer
points to.
 Instead, it answers the question of whether you can safely assign
the address of the object to a pointer of a particular type.
 dynamic_cast<target_type> (expr)
 Two types of casting:
 Upcasting – casting from derived to base
 Downcasting – casting from base to derived (note: base pointer must hold
the address of derived for successful casting)
class base main()
{ { //UPCASTING
public:
16
base *bp;
virtual void display(){ }; derived *dp;
void show() bp=dynamic_cast<base*>(dp);
{ cout<<"Base Class"<<endl; } if(bp)
}; cout<<"Upcasting successful"<<ends;
class derived : public base bp->show();
{
public: //DOWNCASTING
void show() base *bp1=new derived;
{ cout<<"Derived Class"<<endl; } derived *dp1;
}; dp1=dynamic_cast<derived*>(bp1);
if(dp1)
Output : cout<<"Downcasting successful"<<ends;
Upcasting successful Base Class dp1->show();
Downcasting successful Derived Class }
typeid operator 17

 typeid is an operator which allows you to access the type of


an object at runtime
 Can also be implemented for non-polymorphic class
 This is useful for pointers to derived classes
main()
class Animal
{
{ 18
Animal *ap=new Cat;
public:
Cat c;
virtual void show()
int roll;
{
float marks;
cout<<"Animal Class"<<endl;
cout<<"Type of ap="<<typeid(ap).name()<<endl;
}
cout<<"Type of ap="<<typeid(*ap).name()<<endl;
};
cout<<"Type of c="<<typeid(c).name()<<endl;
class Cat:public Animal
cout<<"Type of roll="<<typeid(roll).name()<<endl;
{
cout<<"Type of marks="<<typeid(marks).name()<<endl;
public:
}
void show()
Type of ap=P6Animal
{ Type of ap=3Cat
cout<<"Cat Class"<<endl; Type of c=3Cat
} Type of roll=i
}; Type of marks=f

You might also like