18

如果你有这样的结构

struct A {
    void func();
};

和像这样的参考

A& a;

您可以像这样获得指向其func方法的指针:

someMethod(&A::func);

现在,如果该方法是虚拟的并且您在运行时不知道它是什么,该怎么办?为什么你不能得到这样的指针?

someMethod(&a.func);

是否可以获得指向该方法的指针?

4

3 回答 3

30

指向成员的指针考虑了它们所指向的函数的虚拟性。例如:

#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()
于 2011-07-19T22:22:43.667 回答
11

调用函数指针的方法是同时提供其对象的实例指针。这将解决所有虚拟性问题:

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 * pBasil * p,我可以Basil通过p->Basil::foo(). 如果给我一个,我怎么能做同样的事情void(Derrek::*q)() = &Derrek::foo

回答:这是做不到的。单独的 PMFq不知道它是否指向一个虚函数,更不用说是哪个虚函数了,而且它不能用于在运行时查找基类函数。[感谢史蒂夫和卢克!]

于 2011-07-19T22:21:25.100 回答
1

您可以获得指向它的指针,如下所示:

struct A {
    virtual void foo() = 0;
};

typedef void (A::*LPFOO)();

LPFOO pFoo = &A::foo;
于 2011-07-19T22:23:04.847 回答