Your classes have no virtual table pointer since they have no virtual functions.
And like you said, even if they had, how virtual functions are implemented is not specified by C++ – every compiler can do it differently, there is no requirement for the existence of a vtable.
In practice, the sane implementation (for single inheritance) is to have a virtual table pointer at the beginning of the class, and after it the normal class members. There is no such thing as “method pointers” – normal member functions are resolved at compile time, and virtual functions have their pointers in the vtable in the order of their declaration.
Here’s an example layout:
struct Base { + Base ------------+ + Base vtable ----+
virtual void foo(); | * vptr ---|---> | * void (*foo)() |
T bases_field; | * base_field | +-----------------+
}; +------------------+
struct Derived { + Derived ---------+ + Derived vtable -+
T derived_field; | * CBase instance |---> | * void (*foo)() |
}; | * derived_field | +-----------------+
+------------------+
(Not to scale for bytes occupied in memory.)
Each instance thus contains a pointer to a virtual table. Per class, there is only one virtual table. I.e. one shared between all instances of CBase
and one shared between all instances of CDerived
.