C++ Pointer to virtual function
If you have a struct like this one
struct A {
void func();
};
and a reference like this one
A& a;
you can 开发者_如何学Cget a pointer to its func
method like this:
someMethod(&A::func);
Now what if that method is virtual and you don't know what it is at run-time? Why can't you get a pointer like this?
someMethod(&a.func);
Is it possible to get a pointer to that method?
Pointers to members take into account the virtuality of the functions they point at. For example:
#include <iostream>
struct Base
{
virtual void f() { std::cout << "Base::f()" << std::endl; }
};
struct Derived:Base
{
virtual void f() { std::cout << "Derived::f()" << std::endl; }
};
void SomeMethod(Base& object, void (Base::*ptr)())
{
(object.*ptr)();
}
int main()
{
Base b;
Derived d;
Base* p = &b;
SomeMethod(*p, &Base::f); //calls Base::f()
p = &d;
SomeMethod(*p, &Base::f); //calls Derived::f()
}
Outputs:
Base::f()
Derived::f()
The way to invoke a function pointer is to also provide its object's instance pointer. This will take care of all virtuality issues:
struct A { void func(); };
int main()
{
typedef void (A::*mf)();
A x; // irrelevant if A is derived or if func is virtual
mf f = &A::func; // pointer-to-member-function
A* p = &x; // pointer-to-instance
(p->*f)(); // invoke via pointer
(x.*f)(); // invoke directly
}
OK, interesting syntax challenge question: Suppose I have this.
struct Basil { virtual void foo(); virtual ~Basil(); };
struct Derrek : public Basil { virtual void foo(); };
Now if I have Derrek * p
or a Basil * p
, I can invoke the Basil
member via p->Basil::foo()
. How could I do the same if I was given a void(Derrek::*q)() = &Derrek::foo
?
Answer: It cannot be done. The PMF q
alone does not know whether it points to a virtual function, let alone which one, and it cannot be used to look up a base class function at runtime. [Thanks to Steve and Luc!]
You can get a pointer to it, like so:
struct A {
virtual void foo() = 0;
};
typedef void (A::*LPFOO)();
LPFOO pFoo = &A::foo;
精彩评论