Is virtual function table really necessary for C++
OOP polymorphism
In OOP languages, a base-class object pointer can do function call according to the actual type of the object. Let's see an example in Java.
public class Animal{ public void spark(){ System.out.println("spark"); } } public class Dog extends Animal{ public void spark(){ System.out.println("WangWang"); } } public class Cat extends Animal{ public void spark(){ System.out.println("MiaoMiao"); } } public class Main{ public static void main(String[] args){ Animal[] animals=new Animal[3]; animals[0]=new Dog(); animals[1]=new Cat(); animals[2]=new Animal(); for(Animal it:animals){ it.spark() } } }
it will output
WangWang
MiaoMiao
spart
That's "polymorphism".
C++virtual function
Above codes is very natual for Java programmers. However in C++, you can't get such "polymorphism" without the "virtual" keyword decorating the functions. Without "virtual", C++ will output
spark
spark
spark
Take a look at <the virtual table> if you don't yet know about virtual table. This article explains why "virtual" came out, and how virtual function is supported by virtual table.
Why virtual table
Why does C++ use virtual table?
=>Because C++ compiler does not know the actual function address
--->Why?
=>Because C++ compiler does not know the exact type(Cat? Dog? Animal?) of the oject the pointer "panimal" points to
---Why? Is that any way compiler can figure out the object type?
=>Yes! Using "object type tracking"!
object type tracking
Let's consider the sources where an object pointer gets its value. 2 sources indeed.
1. another pointer
2. address of class instance
Where does "another pointer" get its value? Eventually, there's a pointer that gets its value from "class instance".
So, via tracking the assignment thread backwards to the original source object
=> the compiler is able to figure out the exact type of a pointer.
=>the compiler knows the address of the exact function being called
=>no virtual table is needed.
Object type tracking saves both virtual table memery and virtual table pointer of each class instances.
Where does object type tracking not work
Library Linking.
If a library function returns a base-class pointer, there's no way for the compiler to track back to the original source object. The compiler can probably adapt to library code and none-library code. For library classes that are exported out, use virtual table. For other classes, just track theire object type to save memory.
PS: a stackoverflow post I started talking about this problem: click here. Sadly it's proved that Object type tracking failed when there's conditional assignment.
int x; cin >> x; Animal* p; if (x == 10) p = new Cat(); else p = new Dog();
The compiler can't figure out what's the type of p.