Although this is implementation defined there doesn't seem to be much of a real choice.
First of all we can see that you ether have to have a vptr
or an embedded vtable
. The later means that you will have to copy the vtable
on construction and it consumes more memory, but will have the advantage of avoiding one pointer dereference on each method call. There's probably good arguments for both of them depending on the situation - most implementations have chosen to lower construction time and overall memory consumption instead of saving dispatch time.
When chosen vptr
approach we see that we must keep binary compatibility of the layout of base and derived classes. First of all we can achieve this by (often) using one vptr
, this vptr
must for compatibility reasons live in the most basic class.
When dealing with simple inheritance the most straight forward way of converting between derived to base class is to keep the pointer value which will mean that the layout has to be first the fields for the base class followed by the addition derived classes contributes to it.
Now we're quite near the reason why to put the vptr
first. It simply has to be near the beginning of the object as it has to live within the most basic part of the object.
Then for the reason we put it on offset 0 may be that it's a consistent offset that's available for all classes. You simply has no guarantee that there's any data that could be placed before the vptr
.
Putting the vptr
at offset 0 has some advantages too. If you know the object to have a vptr
you know that you would have to look at offset 0 without needing to know the type of the object (more than it has a vptr
). This can come handy for some debugging purposes (the vtable
often contains enough information to deduce the actual type). Especially this makes the typeid
and similar simpler to implement since you only have to look at the same offsets to retrieve the type_info
node via predefined offsets - which means that you can share the actual code for typeid
.