C++ Pointer to virtual function

孤街醉人 提交于 2019-11-28 18:24:16

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

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

You can get a pointer to it, like so:

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

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

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