C++指向虚函数的指针

Chr*_*ris 16 c++ virtual-functions member-function-pointers function-pointers

如果你有这样的结构

struct A {
    void func();
};
Run Code Online (Sandbox Code Playgroud)

和像这样的参考

A& a;
Run Code Online (Sandbox Code Playgroud)

你可以func像这样得到一个指向它的方法的指针:

someMethod(&A::func);
Run Code Online (Sandbox Code Playgroud)

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

someMethod(&a.func);
Run Code Online (Sandbox Code Playgroud)

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

Arm*_*yan 26

指向成员的指针考虑了他们指向的功能的虚拟性.例如:

#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()    
}
Run Code Online (Sandbox Code Playgroud)

输出:

Base::f()
Derived::f()
Run Code Online (Sandbox Code Playgroud)

  • @Chris:成员函数指针很聪明.这就是为什么它们可以比通常的函数指针更大.它们甚至在多重继承的情况下考虑了基类子对象的偏移量 (2认同)

Ker*_* SB 10

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

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
}
Run Code Online (Sandbox Code Playgroud)

好的,有趣的语法挑战问题:假设我有这个.

struct Basil { virtual void foo(); virtual ~Basil(); };
struct Derrek : public Basil { virtual void foo(); };
Run Code Online (Sandbox Code Playgroud)

现在,如果我有Derrek * p或者Basil * p,我可以Basil通过调用该成员p->Basil::foo().如果给我一个,我怎么能这样做void(Derrek::*q)() = &Derrek::foo呢?

答:无法做到.q单独的PMF 不知道它是否指向虚函数,更不用说哪一个,并且它不能用于在运行时查找基类函数.[感谢Steve和Luc!]

  • "语法挑战"所以给定一个指向未知派生类成员函数的指针,你想调用同名的基类成员函数吗?虽然我可能错了,但我认为你不能.关于`p-> Basil :: foo()`的观点是你使用一个完全限定的名称来引用`Basil`的方法 - 只给出一个你不知道函数名称的指针和因此,您不能在完全限定名称中使用相同的符号. (4认同)