Search code examples
c++virtualvtable

C++ Interview: vtable for a class with a pure virtual function


I was asked this interview question today!! (it was a really awkward telephonic interview..):

What is the difference between the vtable for a class with virtual functions and a class with pure virtual functions?

Now, I know the C++ standard doesn't specify anything about vtables, or even the existence of a v-table ..however theoretically speaking what would the answer be?

I blurted out that the class with a pure virtual function could have a vtable and its vtable entry for the pure virtual function will point to the derived class implementation. Is this assumption correct? I did not get a positive answer from the interviewer.

Will a hypothetical compiler create a vtable for a class with only pure virtual functions? What if the class contains pure virtual functions with definitions? (as shown in : http://www.gotw.ca/gotw/031.htm).


Solution

  • In the case of non-pure virtual functions, each entry in the vtable will refer to the final-overrider or a thunk that adapts the this pointer if needed. In the case of a pure-virtual function, the entry in the vtable usually contains a pointer to a generic function that complains and aborts the program with some sensible message (pure virtual function called within this context or similar error message).

    Will a hypothetical compiler create a vtable for a class with only pure virtual functions?

    Yes, it will, the difference will be in the contents stored in the table, not in the shape of the table. In a simplistic approach, a NULL pointer for pure virtual functions, non-NULL for virtual functions. Realistically, a pointer to a generic function that will complain and abort() with usual compilers.

    What if the class contains pure virtual functions with definitions?

    This will not affect the vtable. The vtable is only used for dynamic dispatch, and a call will never be dynamically dispatched to the definition of a pure virtual function (i.e. you can only manually dispatch to the pure virtual function by disabling dynamic dispatch qualifying the name of the type: x.base::f() will call base::f even if it is pure-virtual, but x.f() will never be dispatched to base::f if it is pure virtual.