将新方法的方法指针传递给基类

时间:2014-09-09 06:38:14

标签: c++ vtable

我希望能够从基类中调用派生类中定义的任何仲裁方法(这是通用方法)。基类不了解它们。我想以某种方式得到这个指针和虚拟表偏移并能够调用它。 A类实际上不需要是基类,它可能是一个separete类,它不知道任何关于B但需要调用方法。有可能吗?

class A
{
public:
    typedef void (A::*Method)();

    void call(Method p)
    {
        //...
    }
};


class B : public A
{
public:
    virtual void meth1()
    {
    }
    virtual void meth2()
    {
    }
    virtual void test()
    {
        call(&TestTask::meth1);
        call(&TestTask::meth2);
    }
};

Errors:
test.cpp:420:30: error: no matching function for call to ‘B::call(void (TestTask::*)())’
         call(&TestTask::meth1);
                              ^
test.cpp:420:30: note: candidate is:
test.cpp:402:10: note: void A::call(A::Method)
     void call(Method p)
          ^
test.cpp:402:10: note:   no known conversion for argument 1 from ‘void (TestTask::*)()’ to ‘A::Method {aka void (A::*)()}’
test.cpp:421:30: error: no matching function for call to ‘B::call(void (TestTask::*)())’
         call(&TestTask::meth2);

2 个答案:

答案 0 :(得分:2)

非静态成员函数需要一个对象来执行操作,因此您不能简单地单独调用成员函数指针。在给定该类的对象的情况下,您可以定义一个模板来调用任何类的成员:

template <class Class>
void call(Class & c, void (C::*method)()) {
    (c.*method)();
}

如果这不是你想要的,那么你需要澄清你想要的东西。

答案 1 :(得分:1)

您可以使用CRTP模式来完成您的尝试。

template <typename T> struct A
{
   typedef void (T::*Method)();

   void call(Method m)
   {
      (static_cast<T*>(this)->*m)();
   }
};

struct B : A<B>
{
   void meth1(){}
   void meth2(){}

   void test()
   {
      call(&B::meth1);
      call(&B::meth2);
   }
};