I'm learning C++ and I'm just getting into virtual functions.
From what I've read (in the book and online), virtual functions are functions in the base class that you can override in derived classes.
But earlier in the book, when learning about basic inheritance, I was able to override base functions in derived classes without using virtual
.
So what am I missing here? I know there is more to virtual functions, and it seems to be important so I want to be clear on what it is exactly. I just can't find a straight answer online.
The virtual keyword forces the compiler to pick the method implementation defined in the object's class rather than in the pointer's class.
In the above example, Shape::getName will be called by default, unless the getName() is defined as virtual in the Base class Shape. This forces the compiler to look for the getName() implementation in the Triangle class rather than in the Shape class.
The virtual table is the mechanism in which the compiler keeps track of the various virtual-method implementations of the subclasses. This is also called dynamic dispatch, and there is some overhead associated with it.
Finally, why is virtual even needed in C++, why not make it the default behavior like in Java?
Here is how I understood not just what
virtual
functions are, but why they're required:Let's say you have these two classes:
In your main function:
So far so good, right? Animals eat generic food, cats eat rats, all without
virtual
.Let's change it a little now so that
eat()
is called via an intermediate function (a trivial function just for this example):Now our main function is:
Uh oh... we passed a Cat into
func()
, but it won't eat rats. Should you overloadfunc()
so it takes aCat*
? If you have to derive more animals from Animal they would all need their ownfunc()
.The solution is to make
eat()
from theAnimal
class a virtual function:Main:
Done.
Need for Virtual Function explained [Easy to understand]
Output will be:
But with virtual function:
Output will be:
Hence with virtual function you can achieve runtime polymorphism.
It helps if you know the underlying mechanisms. C++ formalizes some coding techniques used by C programmers, "classes" replaced using "overlays" - structs with common header sections would be used to handle objects of different types but with some common data or operations. Normally the base struct of the overlay (the common part) has a pointer to a function table which points to a different set of routines for each object type. C++ does the same thing but hides the mechanisms i.e. the C++
ptr->func(...)
where func is virtual as C would be(*ptr->func_table[func_num])(ptr,...)
, where what changes between derived classes is the func_table contents. [A non-virtual method ptr->func() just translates to mangled_func(ptr,..).]The upshot of that is that you only need to understand the base class in order to call the methods of a derived class, i.e. if a routine understands class A, you can pass it a derived class B pointer then the virtual methods called will be those of B rather than A since you go through the function table B points at.
Virtual methods are used in interface design. For example in Windows there is an interface called IUnknown like below:
These methods are left to the interface user to implement. They are essential for the creation and destruction of certain objects that must inherit IUnknown. In this case the run-time is aware of the three methods and expects them to be implemented when it calls them. So in a sense they act as a contract between the object itself and whatever uses that object.
I would like to add another use of Virtual function though it uses the same concept as above stated answers but I guess its worth mentioning.
VIRTUAL DESTRUCTOR
Consider this program below, without declaring Base class destructor as virtual; memory for Cat may not be cleaned up.
Output:
Output: