0

我有以下课程设置(此处仅包含相关内容):

// 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(发送者不知道接收者的发布-订阅类型)中定义。

为此,我的想法是使用从to的回调函数(例如 withstd::bind或类似)。但是,我无法实现这一点,因为每当我在编译中包含 Header时都会失败,这是由于循环包含。TaskCommunicationCommunicationTask

所以我不确定如何转发 declare send/ recvfromCommunication以在Task. 我读过这个问题,它很相似,也提供了很好的答案,我想避免CommunicationTask. 在我看来,最好的解决方案似乎是为 的成员引入一种前向声明Communication,但恐怕我不知道如何做到这一点。

我也考虑过课程设置,是否符合目的,但还没有提出更好的解决方案。

4

2 回答 2

1

您可以将声明放在类之外。它不会阻止库仅作为标头,因为您可以使用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定义两个任务方法。

于 2012-09-01T15:56:54.707 回答
1
// 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));
于 2012-09-01T16:51:41.573 回答