[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
In the traditional implementation of vtables, each slot contains three fields: The offset to be added to the this pointer before invoking a virtual function, an unused field that is always zero, and the pointer to the virtual function. The first two fields are typically 16 bits wide. The unused field is called `index'; it may be non-zero in pointer-to-member-functions, which use the same layout.
The virtual table then is an array of vtable slots. The first slot is always the virtual type info function, the other slots are in the order in which the virtual functions appear in the class declaration.
If a class has base classes, it may inherit other bases' vfields. Each class may have a primary vfield; the primary vfield of the derived class is the primary vfield of the left-most non-virtual base class. If a class inherits a primary vfield, any new virtual functions in the derived class are appended to the virtual table of the primary vfield. If there are new virtual functions in the derived class, and no primary vfield is inherited, a new vfield is introduced which becomes primary. The redefined virtual functions fill the vtable slots inherited from the base; new virtual functions are put into the primary vtable in the order of declaration. If no new virtual functions are introduced, no primary vfield is allocated.
In a base class that has pvbases, virtual tables are needed which are used only in the constructor (see example above). At run-time, the virtual tables of the base class are adjusted, to reflect the new offset of the pvbase. The compiler knows statically what offset the pvbase has for a complete object. At run-time, the offset of the pvbase can be extracted from the vbase pointer, which is set in the constructor of the complete object. These two offsets result in a delta, which is used to adjust the deltas in the vtable (the adjustment might be different for different vtable slots). To adjust the vtables, the compiler emits code that creates a vtable on the stack. This vtable is initialized with the vtable for the complete base type, and then adjusted.
In order to call a virtual function, the compiler gets the offset field from the vtable entry, and adds it to the this pointer. It then indirectly calls the virtual function pointer, passing the adjusted this pointer, and any arguments the virtual function may have.
To implement dynamic casting, the dynamic_cast function needs typeinfos for the complete type, and the pointer to the complete type. The typeinfo pointer is obtained by calling the virtual typeinfo function (which doesn't take a this parameter). The pointer to the complete object is obtained by adding the offset of the virtual typeinfo vtable slot, since this virtual function is always implemented in the complete object.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |