Virtual Method
AÂ virtual method is a method declared within a base class and is re-defined (overridden) by a derived class.
The virtual
keyword is used for achieving dynamic dispatch for polymorphic types.
- You should understand the difference between Static vs. Dynamic Type of Pointer and Static and Dynamic Dispatching
Reference
Also see Pure Virtual Function.
Should I declare this method as virtual or not?
YES: Declare
virtual
if you expect this method to be overridden by a descendant class;
- the run-time system will always check to make sure the right implementation is used for any caller
NO: don’t use
virtual
if you are sure it won’t be overwritten, since it’s more efficient to let the compiler know the compiler can hardcode method address instead of doing run-time lookup.
- Risk: If it is overridden, might get “wrong” definition in some situations. See example below.
Example
In the above example,
Moan()
uses Dynamic Dispatching, whileEat()
uses Static Dispatching.As you can see, calling
Eat()
doesn’t not print “cat is eating”.See Static vs. Dynamic Type of Pointer, and Static and Dynamic Dispatching.
From CS247: Which method is called?
This is REALLY important to remember. To understand the differences in dispatching, ask the following questions:
1. Is the method being called on an object?
If so, always use the static type to determine which method is called.
Note
When I was learning this, I never do polymorphism on objects, but rather pointers. Which is one the above doesn’t behave as I expect it.
2. Is the method called via pointer or reference?
This is the way I know it.
- Is the method NOT declared as virtual? Use the static type to determine which method to call.
- Is the method virtual? Use the dynamic type to determine which method is called.
How virtual methods can be useful
Thanks to Virtual Methods, we can support
Each iteration calls a different isHeavy
method.
What about
(*book).isHeavy()
?
(*book).isHeavy()
calls the correct method as well, because*book
yields aBook&
, i.e. a reference.
Declare all methods as virtual?
Why not just declare everything as virtual for simplicity?
Because it takes an additional 8 bytes at least to store a vptr, in addition to the vtable. Consider the example below.
- Declaring
doSomething
as virtual doubles the size of ourvec
object, program consumes more RAM, slower in general. - This extra 8 bytes is storing the vptr - virtual pointer.
- vptr allows us to achieve dynamic dispatch with virtual functions.
Remember, in MIPS, function calls use the JALR instruction. Saves a register, jumps PC to a specific function’s memory address, hardcoded in that machine instruction.
With dynamic dispatch, which function to jump to could depend on user input. Cannot be hardcoded.
How are virtual functions implemented?
See Virtual Method Table.