Do all classes have a Vtable created for them by the compiler?
There are many resources online about VTables. They commonly have the same statement regarding them:
"Whenever a class itself contains virtual functions or overrides virtual functions from a parent class 开发者_如何学Gothe compiler builds a vtable for that class. This means that not all classes have a vtable created for them by the compiler. The vtable contains function pointers that point to the virtual functions in that class. There can only be one vtable per class, and all objects of the same class will share the same vtable."
So why exactly does this mean that not all classes have a vtable created for them by the compiler? Is it because somc classes don't have virtual functions?
Precisely. Some classes don't have a vtable because they don't have any virtual methods.
Virtual methods are methods for which your compiler cannot generate a direct call because it varies depending on the implementation of the class. Vtables are a kind of lookup table that solve this problem by delaying the decision of which implementation to call during the run time of your program: instead of generating a function call, your compiler generates a method lookup on the vtable, then calls the returned method.
Take this example:
class Foo
{
public:
virtual void vMethod()
{
std::cout << "Foo::vMethod was called!" << std::endl;
}
};
class Bar : public Foo
{
public:
virtual void vMethod()
{
std::cout << "Bar::vMethod was called!" << std::endl;
std::cout << "This is not the same as Foo::vMethod." << std::endl;
}
};
Foo* foo = new Bar;
foo->vMethod();
This will print Bar
's message. In most non-trivial scenarios, your compiler cannot know in advance the type of the object on which a virtual method is called. As mentioned above, the vtable solves the problem by providing a uniform lookup mechanism to find method implementations, no matter the type of an object.
A vtable pointer must exist in every instance of a class (which requires the size of a pointer of additional memory, likely to be 4 or 8 bytes), and some insignificant amount of statical memory somewhere in your program's address space. This may not seem a lot to you (and indeed many people would agree), but this can be cumbersome in certain scenarios (like embedded systems where memory is extremely limited). Having vtables for each class would violate the general C++ principle that you pay only for what you use, and therefore the compiler doesn't generate any vtable if it doesn't have to.
Not having a vtable has the notable side effect of disabling runtime type information. If you need to use RTTI in your code, your classes must have at least one virtual method. The convention is to mark the destructor virtual in these cases.
Actually, nothing in C++ requires that any class has a vtable - it's entirely an implementation issue. However, a class with virtual functions must somehow support polymorphic function calls, and this will always require a table/map of some sort. This table/map will be created by the compiler for classes that have polymorphic functions, and might (depending on compiler quality) be created for those that don't.
In addition, some classes don't have a vtable because is explicitly removed, see __declspec(novtable)
(compiler specific)
精彩评论