C++ Pointer to virtual function

霸气de小男生 提交于 2019-12-17 23:29:50

问题


If you have a struct like this one

struct A {
    void func();
};

and a reference like this one

A& a;

you can get 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?


回答1:


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()



回答2:


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!]




回答3:


You can get a pointer to it, like so:

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

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

LPFOO pFoo = &A::foo;


来源:https://stackoverflow.com/questions/6754799/c-pointer-to-virtual-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!