Simple answer is: it depends on the compiler. The standard does not specify how this should be implemented, only how it should behave.
In practice, implementations tend to simply have a derived vtable which begins with the same structure as the base vtable, than appends the derived class methods on the end (that is to say new methods in the derived class, not overrides).
The vtable pointer just points the the beginning of the whole table. If the object is being accessed through a base pointer type, then no one should ever look beyond the end of the base class methods.
If the pointer is of the derived type, then the same pointer will allow access further down the table to virtual methods declared in the derived class.
ADDENDUM: Multiple Inheritance
Multiple inheritance follows the same basic concepts, but quickly becomes complex for obvious reasons. But there's one important feature to bear in mind.
A multiply derived class has one vtable pointer for each of its base classes, pointing to different vtables or different locations in the same vtable (implementation dependent).
But it's important to remember it's one per immediate base class per object.
Thus if you had a multiply derived class with one int
of data and three immediate base classes, the size of each object would actually be 16 bytes (on a 32-bit system; more on 64-bit). 4 for the int
and four each for each of the vtable pointers. Plus, of course, the sizes of each of the base classes themselves.
That means that in C++, interfaces are not cheap. (Obviously there are no true interfaces in C++, but a base class with no data and only pure virtual methods emulates it.) Each such interface costs the size of a pointer per object.
In languages like C# and Java, where interfaces are part of the language, there is a slightly different mechanism whereby all interfaces are routed through a single vtable pointer. This is slightly slower, but means only one vtable pointer per object, however many interfaces are implemented.
I'd still follow an interface style approach in C++ for design reasons, but always be aware of this additional overhead.
(And none of this even touches on virtual inheritance.)