C++ – Virtual Functions

When a class inherits from another class, it is possible to override the public methods of the base-class in the derived-class.

Simply provide an alternate implementation of the method in the sub-class and you are done. This is pretty straightforward and will work perfectly until you try to refer to the derived-class instance using a parent-class pointer. For example, say you have the following two classes.

class Animal{
    public:
    void getInfo(){"I am an animal!";}
};

class Dog: public Animal{
    public:
    void getInfo(){"I am a Dog!";}
};

Here, class Dog publicly inherits from class Animal. The getInfo() method is overridden in it. There are multiple ways to use the above classes in the program.

1)

Dog bruno;
bruno.getInfo();
Output:  I am a Dog!

2)

Dog* bruno = new Dog();
bruno->getInfo();
Output:  I am a Dog!

3)

Animal* bruno = new Dog();
bruno->getInfo();
Output:  I am an Animal!

As you can see, the third example above did not give us the intended results. This happened because of something known as static binding or early binding or static dispatch. As the derived-class object was created using a base-class pointer, compiler ended up calling the method of the base class Animal instead of the derived-class Dog. A similar situation can arise when you decide to use the base-class pointer as a parameter in some function. Assume, you decide to use an external function to call the getInfo() method of the objects that is passed to it as arguments. As this function needs to work for the derived-class as well as the base-class in our example, the ideal way is to keep the base-class pointer as the function parameter. But, again due to static binding, you will fail to get the intended results. It will always call the getInfo() of the base class.

It is in such situations that the virtual functions (virtual methods) comes to the rescue. If you define the overridden method in the base class as virtual, compiler will not perform static binding or in other words, compiler switches to dynamic dispatch.  A virtual table(vtable) is created for each class and this table houses all the override method mappings for the class. In addition to it, compiler adds a virtual pointer member (vptr) to each object that is made to point to the virtual table of the corresponding class(vtable).It is not mandatory to override a virtual function in a sub-class. To make a class method virtual, simply add the keyword ‘virtual’ to the front of the method as shown below.

class Animal{
    public:
    virtual void getInfo(){"I am an animal!";}
};

Pure virtual functions are the virtual functions that must be overridden in the sub classes. Pure virtual functions do not have an implementation in the base class. If you fail to provide an implementation of a pure virtual function in the sub-classes, you will not be able to create instances of these sub-classes.

class Animal{
    public:
    virtual void getInfo() = 0;
};

C++ 11 provides a nifty keyword to mark a sub-class method as an overridden method. Although I called it as a keyword, C++ officially refers to it as a special identifier. Simply add the keyword  ‘override‘ to the method. This will tag the method as an override of a virtual method in the base class. Although this is not really important, it is a good to know feature. This is a handy way to tell the compiler as well as the reader of the code that the method is an override method of some virtual function.

class Dog: public Animal{
    public:
    void getInfo() override {"I am a Dog!";}
};

It is also possible to override a private virtual method of the base class in a derived class. If the private virtual method in the base class is pure, it must be overridden in the derived class.

Virtual functions are generally considered to be slow because it is possible to encounter two additional cache misses.(one for virtual pointer of the object,second for the virtual table). Usually, it is only the low latency C++ programmers that tend to worry about the performance hits due to the use of virtual functions. However, it is best to use virtual functions only when required rather than using them for the sake of it.

One thought on “C++ – Virtual Functions

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s