In C++, base class and derived class is a popular example of a concept that mirrors real life hierarchy.
Apart from that there are several small but really useful concepts that are specially designed to keep the code simple and make life easier for a C++ programmer.
One such concept is C++ virtual functions.
In this tutorial, we will understand virtual functions concept in detail through C++ code examples.
Example Code without Virtual Function
To begin with, let us use the following simple C++ example code that doesn’t use virtual function.
#include <iostream> class A { public: const char* fetchClassName() { return "A"; } }; class B: public A { public: const char* fetchClassName() { return "B"; } }; int main(void) { B obj_b; A &obj_a = obj_b; std::cout << obj_a.fetchClassName() << "\n"; }
Here is the output of the above program :
A
If you observe the logic written in the ‘main()’ function, the object of class A was referring to object of class B. But, still when the function ‘fetchClassName()’ was called through object of class A, the corresponding function of class A was called.
Now, what if we want that ‘fetchClassName()’ of class B to be called under the same circumstances?
Well, this is where the concept of Virtual Functions comes into the picture. Before going further into this concept, lets see how virtual functions can solve the problem in our case.
If you are new to C++, hello world C++ program and C++ constructors and destructors might give you a jumpstart.
Example Code with Virtual Function
Here is the same code but this time the function ‘fetchClassName()’ is made virtual :
#include <iostream> class A { public: virtual const char* fetchClassName() { return "A"; } }; class B: public A { public: virtual const char* fetchClassName() { return "B"; } }; int main(void) { B obj_b; A &obj_a = obj_b; std::cout << obj_a.fetchClassName() << "\n"; }
So, you can see that the function ‘fetchClassName()’ was made virtual by adding the keyword ‘virtual’ in it’s declaration.
Here is the output of the above program. After making the function virtual, the program generates the correct expected output.
B
Now lets understand why making the function ‘fetchClassName()’ impacted the output.
- In the very first example, the object ‘obj_a’ was pointing to the base part of class ‘A’ in class ‘B’. So, when ‘obj_a.fetchClassName()’ was called, the corresponding function of class ‘A’ was called.
- Now, when the function ‘fetchClassName()’ was made virtual, then the ‘virrtual’ keyword made sure that the program searched for a derived version. Which was found in class B and hence function of Class B was called.
So this means that through virtual functions, one can access the functions with similar prototype in the derived class.
The next question is, do we need to make the derived class function ‘fetchhClassName()’ virtual? Well, let’s omit the virtual keyword from it’s prototype :
#include <iostream> class A { public: virtual const char* fetchClassName() { return "A"; } }; class B: public A { public: const char* fetchClassName() { return "B"; } }; int main(void) { B obj_b; A &obj_a = obj_b; std::cout << obj_a.fetchClassName() << "\n"; }
Here is the output in this case :
B
So we see that the virtual keyword is mandatory only with the function of class ‘A’ because this is sufficient enough to allow the program to look for the similar function in the derived class ‘B’. If there would have been a class ‘C’ which would have been derived from ‘B’ then in that case, the function ‘fetchClassName()’ of class ‘C’ would have been called.
Here is an example where Class ‘C’ is also involved :
#include <iostream> class A { public: virtual const char* fetchClassName() { return "A"; } }; class B: public A { public: const char* fetchClassName() { return "B"; } }; class C: public B { public: const char* fetchClassName() { return "C"; } }; int main(void) { C obj_c; A &obj_a = obj_c; std::cout << obj_a.fetchClassName() << "\n"; }
Here is the output of the above program. As you see, because of the virtual nature of the function in Class ‘A’, similar function of Class ‘C’ was executed.
C
Take care of function prototypes
Please note that in order to work properly, the virtual function and all it’s counterparts in derived classes should have same prototype. If there is a prototype mismatch then things might not work as expected.
Here is an example :
#include <iostream> class A { public: virtual const char* fetchClassName() { return "A"; } }; class B: public A { public: const char* fetchClassName() { return "B"; } }; class C: public B { public: const char* fetchClassName(int a) { return "C"; } }; int main(void) { C obj_c; A &obj_a = obj_c; std::cout << obj_a.fetchClassName() << "\n"; }
You can see that the prototype of the function in Class ‘C’ is different in the above sample code.
The following is the output of the above program:
B
The output confirms that the function in Class ‘C’ was not considered as a candidate to be called because of the difference in prototype.
There is one exception to this rule: All the override functions that have a pointer or reference to derived class as return type will get treated as normal functions with exactly same prototype.
Comments on this entry are closed.
A description of virtual functions is not very useful if you don’t say why you would want to implement a function as virtual. Unfortunately it’s possible to write a whole book on this sibject and not cover it all.
C++ has virtual functions so a developer can describe a kind of behavior (by defining the virtual function) in the base class, and then provide several instances of the behavior (by implementing the virtual function) in each of several derived classes. In the example, the behavior being specified is “fetch the class name”, and the various implementations are; return “A”, return “B”, etc.
Usually the base class doesn’t implement the behavior at all, because it represents a type of behavior, not an actual behavior. We might build a family of classes to implement childrens’ building blocks with letters on them (to motivate naming them A, B, and C; all examples are lame, sorry). Then the base class might be called LetterBlock, and it might have virtual functions GetLetter(), GetSound(), and GetPicture(). Derived class A would implement GetLetter() to return “A”, GetPicture() to return a picture of an airplane, and GetSound() would produce a “Whoosh!” sound. Class B would return a picture of a boat, and make the sound of an outboard motor. Each derived class implements a kind of behavior (make a sound, produce a picture) in a different way.
This kind of behavior is called polymorphic, because it is the same type of behavior, but it takes many specific forms.
It’s also meaningful to think of the base class as defining an interface, the set of behaviors to be made available by the family of classes; and the derivations as providing implementations of the interface.
See, you can write a whole book…
I liked the example. Showed with an example how the virtual function works…
Thanks for your contribution.
I wish you good luck in your life.
More on C++ tutorial ..please..
Thanks for the example.
Nice comment from SeattleC++ too. Speaking of “polymorphic” is really important in my opinion.
Would you please tell me where these virtual functions can be used.
Thankyou
nice virtual fuction
I really find it helpful to understand…………
I just ran into this when I made a new C++ file in code blocks.
I have two Mains and I don’t know what the “~” is about.
I am having trouble finding answers on the internet.
#include “Main.h”
Main::Main()
{
//ctor
}
Main::~Main()
{
//dtor
}
this is amazing method, in this way i understand every thing, this clear my concepts , thanks.