指针指向虚函数

C++ Pointer to virtual function

本文关键字:函数 指针      更新时间:2023-10-16

如果你有一个像这样的结构体

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

答案:不能这样做。PMF q本身并不知道它是否指向虚函数,更不用说指向哪个虚函数了,而且它不能用于在运行时查找基类函数。感谢史蒂夫和卢克!)

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

struct A {
    virtual void foo() = 0;
};
typedef void (A::*LPFOO)();
LPFOO pFoo = &A::foo;