从包含的类调用容器类中定义的回调函数的推荐方法是什么?

jpe*_*pen 6 c++ oop

想象一下,您有一个类层次结构,如下所示:

class Robot
{
public:
    void OnTaskCompleted() {}

private:
    Task *m_pTask;
};

class Task
{
public:
    virtual void DoTask() = 0;
};

class TidyUp : public Task
{
public:
    void DoTask()
    {
        // When TidyUp task is compeleted invoke OnTaskCompleted() from here.
    }
};
Run Code Online (Sandbox Code Playgroud)

我需要打电话OnTaskCompleted()TidyUp::DoTask().建议的方法是什么?

我想避免:

  • 使OnTaskCompleted()静态
  • 将Robot指针传递给Task

das*_*ght 5

static除非Robot程序中只有一个,并且该机器人的实例静态可用,否则该路径是不可行的.

传递Robot给任务可能没问题,但它可能会泄露太多信息并禁止使用机器人以外的对象进行任务使用.

第三种方法是为完成通知创建类似接口的类,将其扩展到Robot,并从任务中调用它.不幸的是,C++并没有让你进入虚拟继承领域变得特别容易.

您可以采用POSIX线程库中常见的回调方法(传递void指针和带有void指针的函数指针),但这不是C++ - ish.

最后,如果您使用的是C++ 11,那么您可以使用匿名函数,通过在不使用外部库(如boost)的情况下将函数和操作对象包装在单个闭包中来非常优雅地解决问题.

以下是第三种方法的快速示例(链接到ideone):

#include <iostream>
#include <string>
using namespace std;

class WithNotification {
public:
    virtual void notify()=0;
};

class Robot : public virtual WithNotification {
private:
    string name;
public:
    Robot(const string& n) : name(n) {}
    virtual void notify() {cout << name << " has been notified" << endl; }
};

class Task {
private:
    WithNotification& onFinished;
public:
    Task(WithNotification& f) : onFinished(f) {}
    void run() {
        cout << "The task is running" << endl;
        onFinished.notify();
    }
};

int main() {
    Robot r1("Quick");
    Robot r2("Brown");
    Task t1(r1);
    Task t2(r2);
    t1.run();
    t2.run();
}
Run Code Online (Sandbox Code Playgroud)