VIRTUAL BASE CLASS
AND
VIRTUAL FUNCTION
Need for Virtual Base Classes
• Consider the situation where we have one
class A .
• This class is A is inherited by two other
classes B and C.
• Both these class are inherited into another in
a new class D .
(as shown in figure)
class A are inherited twice to class D.
• data members/function of class A are
inherited twice to class D.
• One through class B and second through
class C.
• When any data / function member of class A is
accessed by an object of class D, ambiguity
arises
• which data/function member would be
called? One inherited through B or the other
inherited through C.
• This confuses compiler and it displays error.
Example
class A {
{ };
public:
void show() class D : public B, public C
{ {
cout << "Hello form A "; };
}
}; int main()
{
class B : public A D object;
{ object.show();
}; }
class C : public A
How to resolve this issue?
• To resolve this ambiguity when class A is
inherited in both class B and class C, it is
declared as virtual base class by placing a
keyword virtual as :
• Syntax for Virtual Base Classes:
• Syntax 1: class B : virtual public A { };
Syntax 2: class C : public virtual A { };
• virtual can be written before or after
the public.
• Now only one copy of data/function member
will be copied to class C and class B and
class A becomes the virtual base class.
Example
class A { };
public:
int a; class D : public B, public C {
A() // constructor };
{ int main()
a = 10; {
} D object;
}; cout << "a = " << object.a;
class B : public virtual A { return 0;
}; }
class C : public virtual A {
Pointers to Derived Classes
• C++ allows a pointer in base class to point to
either base class object or to any derived class
object.
• Pointer declared as a pointer to base class can
also be pointer to derived class.
• Base *ptr; // pointer to class base
• Base b;
• Derived d;
• Ptr=&b; //pointer point to object b
• Ptr=&d; //pointer point to object d
• Using ptr, we can access only those members
of derived class which are inherited from base
and not the members that originally belongs
to derived.
Class base Display()
{ {cout<<b;}
int a; };
Public:
Base() Main()
{a=10;} {
Display() Base *ptr;
{cout<<a;} Base s;
}; Ptr=&s;
Class derived : public base Ptr->display();
{ Derived d;
Int b; Ptr=&d;
Derived() Ptr->display();
{ }
B=20;
}
Solution
• Using Casting(like type conversion), derive
class function display()can be executed.
• ((Derived*)ptr)->display();
• Using Explicit casting: Virtual Function
• Using base class pointer, if we call some
function which is in both classes , then the
base class function is invoked.
• But, if we want to invoke derived class
function using base class pointer.?
• It can be achieved by defining the function as
VIRTUAL in base class.
• This is how virtual function support run-time
polymorphism.
Virtual function/Run-time
Polymorphism/Dynamic Binding
• When we use the same function name in both the
base and derived classes, the function in the base
class declared as virtual.
• By using virtual keyword, C++ determines which
function to use at run-time.
• Based on the type of object pointed to by the base
pointer.
• Thus, by making the base pointer to point to
different objects, we can execute different versions
of virtual functions.
Run-time polymorphism
• C++ supports a mechanism called virtual
function to achieve run-time polymorphism.
• At run-time, when it is known what class
objects are under consideration, the
appropriate version of the function is invoked.
• Since, the function is linked with a particular
class much later after the compilation, this
process is termed as late binding or dynamic
binding.
Early binding/static binding/compile time
binding
• When a compiler is able to select the
appropriate function for a particular call at the
compile-time, then this is called early binding
or static binding or compile time
polymorphism.
class base virtual void show()
{ {
public: cout<<“derived class show\n”;
void display() }
{ };
cout<<“base class display\n”; int main()
} {
virtual void show() base b,*ptr;
{ derived d;
cout<<“base class show\n”; ptr=&b;
} ptr->display();
}; ptr->show();
Class derived:public base ptr=&d;
{ ptr->display();
public: ptr->show();
void display() return 0;
{ }
cout<<“derived class display\n”;
}