CH6_
CH6_
4
class B
{
public:
void show()
{ cout<<"I am in base
show"<<endl; }
// invokes overridden function of base class only
};
// bp[1] ->display(); cannot be invoked
class D:public B
{
public:
void show()
{ cout<<"I am in derived
show"<<endl; } Output:
void display() I am in base show
{ cout<<"I am in derived only"; } I am in base show
}; I am in derived only 5
Need of virtual function
• 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. 6
Virtual function
• 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.
7
main()
{
B b, *bp[2];
class B
D d;
{
bp[0]=&b;
public:
virtual void show() 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()
{ cout<<"I am in derived show"<<endl; }
void display()
{ cout<<"I am in derived
display"<<endl; }
8
};
main()
{
B b, *bp[3];
“Virtual”ness is inherited D1 d;
class B D2 e;
{ public:
virtual void show() bp[0]=&b;
{ cout<<"I am in base show"<<endl; } bp[1] =&d;
}; bp[2] =&e;
class D1:public B
{ public: bp[0] ->show();
void show() bp[1] ->show();
{ cout<<"I am in derived1 show"<<endl; } bp[2] ->show();
}; }
class D2:public D1
{ public:
void show()
{ cout<<"I am in derived2 show"<<endl; } 9
};
Pure Virtual function & abstract class/abstract base class
14
dynamic_cast operator
• 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)
15
class base
{
public:
virtual void display(){ };
void show()
{ cout<<"Base Class"<<endl; }
};
class derived : public base
{
public:
void show()
{ cout<<"Derived Class"<<endl; }
};
Output :
Upcasting successful Base Class 16
Downcasting successful Derived Class
typeid operator
• 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
17
main()
{
class Animal Animal *ap=new Cat;
{ Cat c;
public: int roll;
virtual void show() float marks;
{ cout<<"Type of ap="<<typeid(ap).name()<<endl;
cout<<"Animal Class"<<endl; cout<<"Type of ap="<<typeid(*ap).name()<<endl;
} cout<<"Type of c="<<typeid(c).name()<<endl;
}; cout<<"Type of roll="<<typeid(roll).name()<<endl;
class Cat:public Animal cout<<"Type of marks="<<typeid(marks).name()<<endl;
{ }
public:
void show()
{
cout<<"Cat Class"<<endl;
}
18
};