Although nothing is mandated in the C++ standard, every known C++ implementation uses the same approach: every class with at least a virtual function has a vptr (pointer to vtable).
You didn't mention virtual inheritance which is a different, more subtle inheritance relation; non-virtual inheritance is a simple exclusive relation between a base class subobject and a derived class. I will assume all inheritance relations are not virtual in this answer.
Here I assume we derive from classes with at least a virtual function.
In case of single inheritance, the vptr from the base class is reused. (Not reusing it just wastes space and run time.) The base class is called "primary base class".
In case of multiple inheritance, the layout of the derived class contains the layout of every base class, just like the layout of a struct in C contains the layout of every member. The layout of D
is B1
then B2
(in any order actually, but the source code order is usually kept).
The first class is the primary base class: in D
the vptr from B1
points to a complete vtable for D
, the vtable with all the virtual functions of D
. Each vptr from a non-primary base class points to a secondary vtable of D
: a vtable with only the virtual functions from this secondary base class.
The constructor of D
must initialize every vptr of the class instance to point to the appropriate vtable of D
.