[英]C++ member callback with forward declaration
我正在进行以下课程设置(此处仅提供相关内容):
// 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
定义(发送者不知道接收者的发布 - 订阅类型)。
为此,我的想法是使用从Task
到Communication
的回调函数(例如使用std::bind
或类似函数)。 但是,我无法实现这一点,因为每当我在Task
编译中包含Communication
头时失败,这是由于循环包含。
所以我不确定如何从Communication
转发声明send
/ recv
以在Task
使用它们。 我已经阅读了这个类似的问题并提供了很好的答案, 但我想避免在Task
放置指向Communication
的指针。 在我看来,最好的解决方案是为Communication
成员介绍一种前瞻性声明,但我担心我不知道如何做到这一点。
我也考虑过类设置,它是否符合目的,但还没有提出更好的解决方案。
您可以将声明放在课堂之外。 它不会阻止库只是标题,因为您可以inline
这些函数。 您可以安排以下功能:
// 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
以定义两个任务方法。
// Task.h
#include "Message.h"
class Task {
public:
typedef std::function<void(const MessagePtr&)> SendFunc;
typedef std::function<MessagePtr()> RecvFunc;
private:
SendFunc sendfunc;
RecvFunc recvfunc;
public:
void setSendFunc(SendFunc& f) { sendfunc = f; }
void setRecvFunc(RecvFunc& f) { recvfunc = f; }
send(const MessagePtr &msg) {
if (sendfunc) { /* call sendfunc */ }
}
MessagePtr recv() {
if (recvfunc) { /* call recvfunc */ }
}
};
typedef std::shared_ptr<Task> TaskPtr;
// Communication.h
#include "Base.h"
class Communication : public Base {
public:
void send(const TaskPtr &caller, const MessagePtr &msg);
MessagePtr recv(const TaskPtr &caller);
};
// in a function somewhere
taskptr->setSendFunc(std::bind(Communication::send, communicationInstance, taskptr));
taskptr->setRecvFunc(std::bind(Communication::recv, communicationInstance, taskptr));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.