具有前向声明的 C++ 成员回调

标签 c++ callback c++11

我正在设置以下类(class)(此处仅包含相关内容):

// Message.h
class Message { };
typedef std::shared_ptr<Message> MessagePtr;
// Task.h
#include "Message.h"

/*
 * On include of Communication.h compilation fails.
 */

class Task {
public:
    send(const MessagePtr &msg) {
        // Call to Communication::send
    }

    MessagePtr recv() {
        // Call to Communication::recv
    }
};

typedef std::shared_ptr<Task> TaskPtr;
// Base.h
#include "Task.h"

class Base {
    std::map<TaskPtr, std::vector<TaskPtr>> taskMap;
};
// Runtime.h
#include "Base.h"

class Runtime : public Base { };
// Communication.h
#include "Base.h"

class Message; // Forward declaration

class Communication : public Base {
public:
    void send(const TaskPtr &caller, const MessagePtr &msg);
    MessagePtr recv(const TaskPtr &caller);
};

我的目标是在 Communication 中提供一种独立的通信层让任务相互通信。接收者列表在 taskMap 中定义(发送者不知道接收者的那种发布-订阅)。

为此,我的想法是使用来自 std::bind 的回调函数(例如 Task 或类似函数)至 Communication .但是,我无法实现这一点,因为每当我包含 CommunicationTask 内的标题编译失败,这是由于循环包含。

所以我不确定如何转发声明send/recv来自 CommunicationTask 中使用它们.我读过 this问题,这是相似的,也提供了很好的答案,但是我想避免放置指向 Communication 的指针在 Task 内.在我看来,最好的解决方案是为 Communication 的成员引入一种前向声明。 , 但恐怕我不知道如何实现这一目标。

我也考虑过类(class)的设置,是否符合目的,但还没有想出更好的解决方案。

最佳答案

您可以将声明放在类之外。它不会阻止库成为仅 header 文件,因为您可以内联 那些函数。你可以这样安排功能:

// Task.h
#include "Message.h"

class Task {
public:
    inline void send(const MessagePtr &msg);
    inline MessagePtr recv();
//  ^^^^^^
};

typedef std::shared_ptr<Task> TaskPtr;

// Communication.h
#include "Base.h"
#include "Task.h"

class Communication : public Base {
public:
    void send(const TaskPtr &caller, const MessagePtr &msg);
    MessagePtr recv(const TaskPtr &caller);
};

// Task.impl.h
#include "Communication.h"

inline void Task::send(const MessagePtr &msg) {
    // call Communication::send
}

inline MessagePtr Task::recv() {
    // call Communication::recv
}

并包含 Task.impl.h 以定义两个任务方法。

关于具有前向声明的 C++ 成员回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12228645/

相关文章:

c++ - std::regex_match 和具有奇怪行为的惰性量词

c++ - 如何在 Xcode 中列出当前打开的文件?

javascript - 从内部回调分配变量

javascript - Gulp:调用一个异步函数,该函数在转换函数中提供自己的回调

python - 输入变量值后使用 Dash(来自 Plotly)在仪表板上输出值

c++ - 具有循环依赖性的 CRTP

c++ - 类成员 STL 容器 (const std::array) 的编译时创建,其中填充了元素

c++ - 当一个相对较大的浮点值与两个相对较小的浮点值相乘时,消除误差的最佳算术顺序是什么

c++ - 测试 C++ 轮询套接字功能

c++ - 使用 C++ 容器最小化内存开销(std::map 和 std::vector 太贵了)