1 of 17

VIRTUAL BASE CLASS �AND �VIRTUAL FUNCTION

2 of 17

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)

3 of 17

class A are inherited twice to class D

4 of 17

  • 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.

5 of 17

Example

class A

{

public:

void show()

{

cout << "Hello form A ";

}

};

class B : public A

{

};

class C : public A

{

};

class D : public B, public C

{

};

int main()

{

D object;

object.show();

}

6 of 17

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 { };

7 of 17

  • 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.

8 of 17

Example

class A {

public:

int a;

A() // constructor

{

a = 10;

}

};

class B : public virtual A {

};

class C : public virtual A {

};

class D : public B, public C {

};

int main()

{

D object;

cout << "a = " << object.a;

return 0;

}

9 of 17

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.

10 of 17

  • 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.

11 of 17

Class base

{

int a;

Public:

Base()

{a=10;}

Display()

{cout<<a;}

};

Class derived : public base

{

Int b;

Derived()

{

B=20;

}

Display()

{cout<<b;}

};

Main()

{

Base *ptr;

Base s;

Ptr=&s;

Ptr->display();

Derived d;

Ptr=&d;

Ptr->display();

}

12 of 17

Solution

  • Using Casting(like type conversion), derive class function display()can be executed.

  • ((Derived*)ptr)->display();

  • Using Explicit casting: Virtual Function

13 of 17

  • 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.

14 of 17

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.

15 of 17

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.

16 of 17

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.

17 of 17

class base

{

public:

void display()

{

cout<<“base class display\n”;

}

virtual void show()

{

cout<<“base class show\n”;

}

};

Class derived:public base

{

public:

void display()

{

cout<<“derived class display\n”;

}

virtual void show()

{

cout<<“derived class show\n”;

}

};

int main()

{

base b,*ptr;

derived d;

ptr=&b;

ptr->display();

ptr->show();

ptr=&d;

ptr->display();

ptr->show();

return 0;

}