Search code examples
c++functionpointersvirtual

How does a pointer to virtual function differ from a pointer to a non-virtual one?


And why is it required to use "&" before function in the next piece of code?

void (Mammal::*pFunc) () const=0;
pFunc=&Mammal::Move;

Move() is a virtual function in the basic class and pFunc is a pointer to virtual function in this class. So why we need to use "&"? According to some special properties of virtual function? Or it is simply syntax?


Solution

  • An ordinary function can be called with just its address, so a pointer to an ordinary function is just an address.

    A non-virtual function can also be called with just its address (plus, of course, the this pointer, passed by whatever mechanism the compiler uses), so a pointer to a non-virtual function could be just an address.

    A virtual function has to be looked up by a compiler-specific mechanism (usually a vtable, at a known offset in the object; the address of the function is found by indexing into the table), and a pointer to virtual function has to contain whatever information is needed to determine what the actual function to call is, depending on the actual type of the object.

    But a pointer to member function has to be able to handle both virtual and non-virtual functions, so it will have enough room for the right mechanism for both, and the runtime call will check the stored data to figure out what to do.

    Some compilers provide an alternative, where if you promise that you will absolutely, positively, never store a pointer to virtual function in the pointer, the compiler will generate a smaller pointer representation, and you'll find that you're in trouble later when you break that promise.

    As to why the & is required, it's required. Microsoft's early C++ compilers didn't require the & (and didn't require the class name; if you left it out you'd get a pointer to the member function of the class of the current object); they talked about proposing eliminating the rule, but it didn't get anywhere.