The pointer to member function in c++ is in three parts:
Offset
Address/index
virtual?
Offset is used for Pointer adjustment when derived object is called using base pointer.
How is this offset implemented? Is it pointer to some table, one table for each derived class and the table contains entries of the form (base X, offset)
?
Also, where can I get more info about this?
First you should note that a C++ method can be implemented (and is normally implemented) just as a regular function that accepts an extra hidden parameter before all other parameters, named
this
.In other words in
the machine code for
doIt
is the same that would be generated by a C compiler forand a call like
p->doIt(10, 3.14)
is compiled toP2d$vid$doIt(p, 10, 3.14);
Given this a method pointer for a simple class that has no virtual methods can be implemented as a regular pointer to the method code (NOTE: I'm using
vid
for "Void of Int+Double" as a toy example of the "name mangling" that C++ compilers do to handle overloads - different functions with the same name but different parameters).If the class has virtual methods however this is no more true.
Most C++ compilers implement virtual dispatching unsing a VMT... i.e. in
the code for a call like
p->doIt(10, 3.14)
wherep
is aP2d *
is the same that a C compiler would generate fori.e. the instance contains a hidden pointer to a virtual method table that for each member contains the effective code address (assuming the compiler cannot infer that the class of
p
is indeedP2d
and not a derived, as in that case the call can be the same as for a non-virtual method).Method pointers are required to respect virtual methods... i.e. calling
doIt
indirectly using a method pointer on an instance derived fromP2d
is required to call the derived version while the same method pointer is instead to call the base version when used onP2d
instances. This means the selection of which code to call depends on both the pointer and the class instance.A possible implementation is using a trampoline:
and in this case a method pointer is still just pointer to code (but to the trampoline, not to the final method).
An alternative would be to store as method pointer the index of the method inside the VMT instead. This would be feasible because in C++ the method pointer is tied to a specific class and therefore the compiler knows if for that class there are virtual methods or not.
Multiple inheritance do not complicate things for method pointers because everything can be just resolved to a single final VMT table at compile time.