Why virtual tables are used to resolve function calls?
In the follwing as i understand the compiler validates the pointer assignment A *p_a = &b;
knowing it points to derived class object. but why does it require virtual table to resolve the function call?
class A
{
public:
A():x(1){}
virtual vo开发者_运维知识库id getX() {cout << x << endl;}
private:
int x;
};
class B : public A
{
public:
B() : A(),x(2){}
void getX() {cout << x << endl;}
private:
int x;
};
int main()
{
B b;
A *p_a = &b;
p_a->getX();
}
In this case, the compiler could theoretically resolve that call at compile time. But what about?
A* o;
if (userClicksWidgetA())
o = new A();
else
o = new B();
o->method();
That call can't be resolved at compile time. Or what about a separately compiled module which has a method taking an A*
, but it knows nothing about B
; or which contains subclass C
which you know nothing about, and it passes you back an A*
? Ultimately, the vtable is the only runtime representation of the object's class.
If the compiler is smart enough, it might be able to dispatch the call directly, without going through the virtual table, as it has enough information to know the exact type of the final overrider
by looking at the assignment in the line before.
In general the compiler will not have that much information, it will only have a pointer to an A
object, but will not know what the most derived type of the pointed object is. That is when it has to use the virtual table. Basically the virtual table pointer stored in each polymorphic object contains the final object's type information, in particular which is the final overrider
for each one of the methods.
Each object has a pointer to a virtual table function pointer.
When a function is called on an object via redirection of the virtual table the appropriate function is called.
I.e. when you declare an object of type A in your code but it really points to an object of type B, then the function implementation of type B should be called at runtime.
But which function should be called is determined by the vtable. Without the vtable it would not be possible to determine if the function f() of A class should be called or f() of B() which overrides the corresponding function of base class.
This is the C++ design decision on the implementation of polymormism and no other runtime type info is associated with the object (unlike java)
Because thats the way C++ implements polymorphism.
Because determining the actual function to call at compile time would make implementing C++ compilers extremely difficult.
精彩评论