我正在设置以下类(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
.但是,我无法实现这一点,因为每当我包含 Communication
时Task
内的标题编译失败,这是由于循环包含。
所以我不确定如何转发声明send
/recv
来自 Communication
在 Task
中使用它们.我读过 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/