Sunday, Nov 18th

Last update12:59:40 PM GMT

Virtual Functions

Write e-mail

One of the first steps moving to C++ from C after learning Inheritance is the concept of Virtual functions. To put it plainly, Virtual functions are used to have different functionality in the derived classes of a base class when the decision as to which functionality is required is to be taken at the runtime (and is unknown in advance at the compile time). This is achieved through “late binding”. Suppose we have the following classes.

argaiv1879

class Shape // Base class 
 {
 public:
  void create()
  {
   cout<< “Drawing a shape on the screen”;
  }
 };
class Triangle : public Shape //Derived class
 {
 public:
  void create()
  {
  //some code to draw a triangle on the screen
  }
 };
class Line : public Shape //Derived class
 {
 public:
 void create()
  {
  //some code to draw a line on the screen
  }
 };

and similarly other derived classes for shapes like: Square, rectangle, Pentagon etc.....

Now we wish to make an interactive program where the user is asked to input the name of any shape and the corresponding shape will be drawn on the screen. This is where virtual functions come handy.

Lets go step by step. What if we dont have the concept of virtual functions. We first declare some objects like below:

Line obj_line;
shape * pShp ;
pShp = &obj_line;
pShp->create();

Is the assignment in line 3 permissible? Yes it is. The pointer of a base class can point to an address of a derived class. This is called “upcasting”

Now which create() function will be called in the last statement? Its the base class’. Under normal case like above the compiler always gives the first preferences to the member function that matches the type of pointer (and not to the function matching the type of address its pointing to). Now we do a slight modification in the base class:

class Shape // Base class 
 {
 public:
 virtual void create()
 {
 cout<< “Drawing a shape on the screen”;
 }
 };

With the addition of the virtual keyword,the same statement:

pShp = &obj_line;
pShp->create();

will now call the member function of the class Line. :) Now if we come back to our problem statement, we now have a fair enough idea how to achieve what is asked in it. Yes, you are right. Now our job is to just assign the pointer pShp of the base class to the address of any of the derived class objects (Triangle, Line, Rectangle, Square etc) based on user input. Subsequently any call pShp->create() will call the create() function of the derived class that the base class pointer is pointing to.

Please note here that which create function will be called, this decision cannot be taken at compile time and is taken at runtime (Late Binding). We will study the internal mechanism of virtual functions in detail in subsequent article.

One thing to reason out here is that, we are not going to call the create() function of Shape class anywhere in our program and it doesnt even make sense in most of such cases. Moreover, we might even require to prevent the developer to access the create() method of base class even accidentally.

So is it really necessary to have the definition of create() method in Shape class. No it is not !! Most of the times what we employ in our code are pure virtual functions.

class Shape // Base class 
{
public:
 virtual void create() = 0; //pure virtual function

};

The above notation ensures that create() method of base class Shape never gets called and any attempt to do so raises error at compile time.  The pure virtual functions do not have a body. Any class having at least one pure virtual function is called an abstract class. An abstract class cannot be instanciated and should always be inherited. In a pure virtual function we dont need to define the body in the base class but the idea of completely removing the function from the base class "Shape" altogether will be over ambitious. This will give compilation error as the call " pShp->create()" in that case will not have any meaning.

In the next article, we explore deep into how virtual functions are implemented using VTABLE and VPTR. Click here to continue reading !! :-)

Share this post



Add comment

Please refrain from using slang or abusive language in the comments.
To avoid waiting for your comment to be published after being reviewed, please log in as a registered user.


Security code
Refresh

Web Hosting