David,
No, it works like this. You have an object (a "this" pointer). If there are virtual functions for the class of that object, a (hidden) member variable of the class is a pointer to it's VTable. So, suppose the "this" pointer is in a register (highly likely), say EAX. (If it is not, but is a function argument passed by reference, we get it off the stack with (say)
mov EAX, [EBP + 12]
). Then to get the pointer to the virtual function table, we need
mov ECX, [EAX + 0] // If 0 is the offset of the VFT pointer (which it actually is).
Now, we are calling a named virtual function, say MyVirtualFunc(). The compiler knows what offset this is stored in the VFT, say 20. Then all we need is (after pushing parameters)
call [ECX + 20]
Note there are only 2 more instructions than calling a function directly, and this is assuming we have neither the "this" pointer or its VFT pointer already in a register (in reality, we probably have one or both of these).
As you can see, virtual functions are extremely efficient. Note that the above is valid for both base classes and derived classed - hence why virtual functions work. All that differs for base and derived classes is the VFT pointer at this[0] refers to a different VFT. There is no run-time type checking at all (the type checking is implicit in the fact that every such object when constructed by the compiler has a pointer to it's own class's VFT, not that of a base or derived class).
Don't worry about performance of virtual functions!
Neil. |