Did you ever think, what happens if you take a member pointer to a virtual function of a class, and then call it on another instance of derived class (that overrides that member)?
What if you do the same for nonvirtual function?
Here’s a test:
#include <iostream> class A { public: virtual void f() { std::cout << "A::f()\n"; }; void g() { std::cout << "A::g()\n"; }; }; class B : public A { public: virtual void f() { std::cout << "B::f()\n"; }; void g() { std::cout << "B::g()\n"; }; }; typedef void (A::*VirtualFunctionPointer) (); int main() { A a; B b; B* pb = &b; VirtualFunctionPointer p = &A::f; (pb->*p) (); p = &A::g; (pb->*p) (); return 0; }
Answer is in comments.
3 Comments
Both MSVC and gcc print:
B::f()
A::g()
which means member function pointer keeps both function address and VMT index.
And probably a flag telling if it’s virtual.
Probably repeating your answer, but this is indeed quite natural.
p = &A::f;
is a pointer to a virtual function and compiler knows it, therefore it is a pointer to an entry in vtable (of pb object) and is treated by compiler as such.
p = &A::g;
is a pointer to a regular function and compiler knows it, therefore it is a pointer into the chunk of memory that contains the code of A::g() function. Compiler just does type matching whether p function makes sense for bp object.
Astra, right.
Interesting thing is that same “pointer” variable keeps two values, which is not evident.
One Trackback/Pingback
[…] take another, simpler C++ quiz about member pointers. Please bookmark this post: These icons link to social bookmarking sites where readers can share […]
Post a Comment