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(送信者が受信者を知らない種類の発行-購読) 内で定義されます。

この目的のために、私の考えは、コールバック関数を使用することです(たとえば、std::bindまたは同様のもの) from Taskto Communication。ただし、循環インクルードが原因で、コンパイルにCommunicationヘッダーを含めるたびに失敗するため、これを実装することはできません。Task

sendしたがって、declare / recvfromCommunicationを転送して 内で使用する方法がわかりませんTask。私はこの質問を読んことがCommunicationありますTask. のメンバーに一種の前方宣言を導入することが最善の解決策のように思えますが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、2 つのタスク メソッドを定義するためにインクルードします。

于 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 に答える