gpt4 book ai didi

c++ - 将回调从管理器类注册到工作器类,而工作器在执行回调时不必引用管理器

转载 作者:太空宇宙 更新时间:2023-11-04 11:23:18 24 4
gpt4 key购买 nike

我在将我计划的设计转化为 C++ 代码时遇到了一些麻烦。

我有一个 Manager 类,它将创建另一个类 SomeClass 的一些实例。这些实例将在单独的线程中完成一些工作。其中一个实例将被指定为 theOne 并在完成任务时以某种方式通知管理器。从该通知中,管理器应使用某些函数 getData() 获取所有其他实例的结果(如果可用)。

我想我可以通过回调样式通知来实现这一点。从某种意义上说,管理器在实例化类(即 theOne)中将其 getData() 函数注册为回调。如果 theOne 完成了它的工作,它只会调用它的 isDone() 成员,它会在管理器中执行注册的回调。但是这样做 SomeClass 总是需要引用 Manager 实例,我实际上不想要,因为我只希望经理知道 SomeClass(实例)而不是相反。

有什么办法可以解决这个问题吗?还是我的设计不适合那个?如果不是,是否有另一种更合适的设计可以实现这一点。

这是我得到的代码(改编自 here )。我在 main() 中进行的调用当然会在相应的类成员中调用。

#include <functional>
#include <iostream>

class Manager {
public:
void getData(int)
{
std::cout << "Got it!";
}
};

class SomeClass {
public:
SomeClass() : callback() { }
typedef std::function<void(Manager*, int)> Callback;

void registerCallback(const Callback& c)
{
callback = c;
}

void isDone(Manager* p)
{
callback(p, 42);
}
private:
Callback callback;
};

int main()
{
// This should be called in the manager class, which will instanciate its
// SomeClass workers. This works fine.
SomeClass sc;
sc.registerCallback(&Manager::getData);

// This should be called in SomeClass.
// The manager object is needed for the execution of the callback, which I
// want to omit.
Manager cb;
sc.isDone(&cb);
}

最佳答案

您可以使回调成为通用的,并传递一个捕获指向 Manager 指针的函数对象:

// in SomeClass
typedef std::function<void(int)> Callback;
Callback callback;

并根据需要实例化。例如,在管理器中:

// in Manager
using namespace std::placeholders;
auto f1 = std::bind(&Manager::getData, this, _1);
auto f2 = [this](int i) { getData(i); }
SomeClass sc;
sc.registerCallback(f1);
sc.registerCallback(f2);

或其他地方:

void foo(int i) { std::cout << "foo called with i = " << i << "\n"; }

SomeClass sc;
sc.registerCallback(foo);

关于c++ - 将回调从管理器类注册到工作器类,而工作器在执行回调时不必引用管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27541927/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com