如果您有这样的结构体
struct A {
void func();
};
还有像这样的引用
A& a;
你可以通过以下方式获取其func
方法的指针:
someMethod(&A::func);
那么如果该方法是虚拟的,并且你在运行时不知道它是什么?为什么不能像这样获取指针?
someMethod(&a.func);
是否有可能获得指向该方法的指针?
如果您有这样的结构体
struct A {
void func();
};
还有像这样的引用
A& a;
你可以通过以下方式获取其func
方法的指针:
someMethod(&A::func);
那么如果该方法是虚拟的,并且你在运行时不知道它是什么?为什么不能像这样获取指针?
someMethod(&a.func);
是否有可能获得指向该方法的指针?
成员指针会考虑它们所指向的函数的虚拟性。例如:
#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()
}
输出:
Base::f()
Derived::f()
调用函数指针的方法是同时提供其对象实例指针。这将解决所有虚拟性问题:
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
}
好的,有趣的语法挑战问题:假设我有以下代码。
struct Basil { virtual void foo(); virtual ~Basil(); };
struct Derrek : public Basil { virtual void foo(); };
如果我有 Derrek * p
或者一个 Basil * p
,我可以通过 p->Basil::foo()
来调用 Basil
类的成员。如果给我一个 void(Derrek::*q)() = &Derrek::foo
,我该如何做呢?
答案:无法实现。仅仅拥有 PMF q
是不够的,它并不知道它指向的是一个虚函数,更何况是哪个虚函数,而且它不能在运行时被用于查找基类的函数。[感谢 Steve 和 Luc!]
x
是多态的话,那么直接调用 x.func()
会导致在类的 vtable 中查找 func
的最终派生位置。 - Kerrek SBp->Basil::foo()
的关键在于使用全限定名称引用Basil
方法 - 只有给定指针,你不知道函数的名称,因此无法在完全限定名称中使用同一符号。 - Steve Jessop你可以这样获取它的指针:
struct A {
virtual void foo() = 0;
};
typedef void (A::*LPFOO)();
LPFOO pFoo = &A::foo;