2012-09-01 8 views
0
(여기에만 관련 내용) 나는 다음과 같은 클래스 설정하는 데 문제가

와 회원 콜백 :C++ 앞으로 선언

// 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 헤더를 포함 할 때마다 원형 포함으로 인해 컴파일이 실패하므로이 기능을 구현할 수 없습니다.

따라서 전달 방법에 대해서는 send/recv에서 Communication으로 Task 내에서 사용하는 것이 확실하지 않습니다. 나는 this 질문을 읽었으며 이는 비슷하고 좋은 답변을 제공합니다. 그러나Communication에 포인터를 두지 않으려합니다. Task 내에 있습니다. 최선의 해결책은 회원에게 Communication에 대한 일종의 전진 선언을 소개하는 것 같지만, 이것을 수행하는 방법을 모르겠다.

나는 목적에 맞는 클래스 셋업에 대해서 생각해 봤지만 더 나은 해결책은 아직 나오지 않았다.

+0

당신은 일이있는 헤더에 선언 된 분명하므로 별도의 조각으로 코드를 분리 할 수 ​​있습니까? 콜백 함수를 삽입 할 수있는 위치를 보여주는 주석이 있습니까? – Oktalist

+0

완료, 현재 include 및 컴파일 포함 오류에 대한 메모도 추가되었습니다. –

+0

니스. 이제'Task :: send()'와'recv()'는'Communication'의 인스턴스를 어디에서 가져 옵니까? 클래스 정의 나 별도의'Task.cpp' 파일에 인라인 함수를 실제로 정의하고 있습니까? (이것들에 간단한 답을 줄 수 있다면 코드를 편집 할 필요가 없습니다.) – Oktalist

답변

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을 포함한다.

+0

오! 다른 헤더를 정의하고'인라인 (inline) '을 사용하는 것을 생각하지 마십시오. 감사. –

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)); 
+0

해당 솔루션을 주셔서 감사합니다, 나는 헤더를 직접 대상으로하기 때문에 다른 하나를 받아 들였습니다,하지만 나는 또한 하나 upvoted했습니다. –