Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将函数作为参数从派生类传递给父方法_C++_Inheritance - Fatal编程技术网

C++ 将函数作为参数从派生类传递给父方法

C++ 将函数作为参数从派生类传递给父方法,c++,inheritance,C++,Inheritance,我有以下代码,其中execute()方法接受函数作为参数并执行它。然后start()方法调用execute()以运行method1() 现在我想修改它,以便实现以下目标: 创建一个名为TestRunner的基类,并将execute()方法移动到该基类中 让Test从TestRunner继承,在那里它可以调用execute()方法来运行其本地方法 我正在尝试以下操作,但遇到了如何在execute()中指定方法参数的问题,即我现在使用的TestRunner::*func class TestRu

我有以下代码,其中
execute()
方法接受函数作为参数并执行它。然后
start()
方法调用
execute()
以运行
method1()

现在我想修改它,以便实现以下目标:

  • 创建一个名为
    TestRunner
    的基类,并将
    execute()
    方法移动到该基类中
  • Test
    TestRunner
    继承,在那里它可以调用
    execute()
    方法来运行其本地方法
我正在尝试以下操作,但遇到了如何在
execute()
中指定方法参数的问题,即我现在使用的
TestRunner::*func

class TestRunner
{
  public:
    TestRunner()
    {
       //Do something...
    }
  protected:
    void execute(void(TestRunner::*func)(void))
    {
      (this->*func)();
    }
}

class Test : TestRunner
{
    public:
      Test() : TestRunner()
      {

      }

      int start()
      {
        TestRunner::execute(&Test::method1);
        return 1;
      }

    private:
      void method1(void)
      {
        //Do something
      }    
}
如果我按原样编译代码,显然会出现以下错误:

对“Test::execute(void(Test::*)()”的调用没有匹配的函数

参数1没有从“void(Test:)()”到“void”的已知转换 (测试人员::)()'


有人能在这里为我指引正确的方向吗?或者我需要做一些完全不同的事情来实现我想要的吗?

我在这里用这个答案来想出一个解决方案:

创建回调类:

class Callback
{
    public:
        virtual ~Callback() { }
        virtual void doSomething()=0;
};
扩展回调类以定义如何执行函数和使用模板:

template<class T>
class BCallback: Callback
{
    public:
        ~BCallback() { }
        BCallback(T *obj, void(T::*fn)()): obj_(obj), fn_(fn) { };

        void doSomething()
        {
            (obj_->*fn_)();
        }

    private:
        T *obj_;
        void(T::*fn_)();
};
从派生类运行该方法:

class Test: TestRunner
{
    public:
        int start()
        {
            BCallback<Test> cb(this, &Test::method1);
            this->execute(&cb);
            return 1;
        }

    private:
        void method1(void)
        {
            //Do something
        }   
};
类测试:TestRunner
{
公众:
int start()
{
b回拨cb(此,测试::方法1);
此->执行(&cb);
返回1;
}
私人:
作废方法1(作废)
{
//做点什么
}   
};

您可以像这样使用
typedef

typedef void(Test::*Callback)(void);
然后,您可以使执行函数接受类型为
回调
的对象。它看起来像是Test::execute(Callback)

调用它时,请使用
静态\u cast


通过这种方式,您可以避免仅仅为了做一件简单的事情而编写整个两个新类(其中一个甚至是模板!)。作为奖励,您可以使用函数重载来获取不同函数签名的
Test::execute

虚拟方法有什么问题?看起来像是一个问题。@MohamadElghawi想详细说明一下吗?@RSahu我想我很清楚我要实现的目标和尝试的解决方案…我需要一个类从另一个类继承,从派生类可以调用父类中的方法,并将另一个类作为参数传递给它。@SeverusSnape,我知道这是您的实现策略。我认为这不是真正的问题。无论如何,唯一可以做到这一点的方法是在基类中使用或使用
virtual
成员函数。
class Test: TestRunner
{
    public:
        int start()
        {
            BCallback<Test> cb(this, &Test::method1);
            this->execute(&cb);
            return 1;
        }

    private:
        void method1(void)
        {
            //Do something
        }   
};
typedef void(Test::*Callback)(void);
Test tester;
tester.execute(static_cast<Callback>(&DerivedTest::someMethod));
Test::execute(Callback cb) {
    (this->*cb)();
}