c++virtual-table

cpp class size with virutal pointer and inheritance


class A{
    virtual void a();
};  
class B : A{
    virtual void a();
};
class C{
    virtual void a();
};
class E : A, C{
    virtual void a();
};

int main(){
    std::cout << (sizeof(B)) << "\n"; // 4
    std::cout << (sizeof(C)) << "\n"; // 4
    std::cout << (sizeof(E)) << "\n"; // 8
}

in 32 bits system linux

why sizeof(B) and sizeof(C) are both 4

for class C, it has a virtual function, so there is a virtual pointer hidden in class c which is 4 bytes

but why class B's size is also 4. I think it exists two pointers in class B, one is for B itself since class B has a virtual function, one is for A.

Then same problem for E?

any help is appreciated


Solution

  • No, there is only one vtable pointer in every object which uses virtual functions, independently if the virtual function was defined in the class itself or the class derives from another class which uses virtual functions.

    What the compiler generates is a table of function pointers, so that every class ( not instance/object ) has its own. In your example you have a table for class A, one for class B and so on. And in every object/instance you have a vtable pointer. This pointer points only to the table. If you call a virtual function via class pointer, you have the indirection over the vtable pointer and than over the vtable itself.

    As a result every instance of a class keeps only a single vtable pointer, pointing to the vtable for this class. As you can see, this results in the same size for every instance of every class you wrote.

    In the case of multiple inheritance, you will get multiple vtable pointers. A more detailed answer is already given here: vtable and multiple inheritance

    BTW: That you have a vtable and a vtable pointer is not guaranteed from the standards, every compiler can do what it want if the result is what we expect from the semantic. But the double indirection via vtable pointer to pointer in the table to the function is the typical implementation.