Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do all classes have a Vtable created for them by the compiler?

Tags:

c++

vtable

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 the 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?

like image 351
xarzu Avatar asked Apr 18 '11 23:04

xarzu


1 Answers

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.

like image 139
zneak Avatar answered Sep 21 '22 23:09

zneak