Understandig Virtual Tables in C++on C++
What does dynamic dispatch mean? PermalinkIn this context, dispatching just refers to the action of finding the right function to call. In the general case, when you define a method inside a class, the compiler will remember its definition and execute it every time a call to that method is encountered. Consider the following example:
Here, the compiler will create a routine for So, what do vtables have to do with all this? PermalinkWell, there are cases where it is not possible for the compiler to know which routine to execute at compile time. This is the case, for instance, when we declare virtual functions:
The thing about virtual functions is that they can be overriden by subclasses:
Now consider the following call to
If we use static dispatch as above, the call Hopefully you can see the problem by now: given that virtual functions can be redefined in subclasses, calls via pointers (or references) to a base type can not be dispatched at compile time. The compiler has to find the right function definition (i.e. the most specific one) at runtime. This process is called dynamic dispatch or late method binding. So, how do we implement dynamic dispatch? PermalinkFor every class that contains virtual functions, the compiler constructs a virtual table, a.k.a vtable. The vtable contains an entry for each virtual function accessible by the class and stores a pointer to its definition. Only the most specific function definition callable by the class is stored in the vtable. Entries in the vtable can point to either functions declared in the class itself (e.g. In our example, the compiler will create the following virtual tables: The vtable of class More interesting is Note that vtables exist at the class level, meaning there exists a single vtable per class, and is shared by all instances. Vpointers PermalinkYou might be thinking: vtables are cool and all, but how exactly do they solve the problem? When the compiler sees Very true, I still need to tell the second part of the story: vpointers. Every time the compiler creates a vtable for a class, it adds an extra argument to it: a pointer to the corresponding virtual table, called the vpointer. Note that the vpointer is just another class member added by the compiler and increases the size of every object that has a vtable by Hopefully you have grasped how dynamic function dispatch can be implemented by using vtables: when a call to a virtual function on an object is performed, the vpointer of the object is used to find the corresponding vtable of the class. Next, the function name is used as index to the vtable to find the correct (most specific) routine to be executed. Done! Virtual Destructors PermalinkBy now it should also be clear why it is always a good idea to make destructors of base classes virtual. Since derived classes are often handled via base class references, declaring a non-virtual destructor will be dispatched statically, obfuscating the destructor of the derived class:
This will output:
Making
Wrapping up Permalink
|
|
来自: astrotycoon > 《深度理解C 》