2011-07-05 3 views
2

안녕하세요, 일부 코드를 컴파일하는 데 문제가 있습니다. A가 의존하고 B가 A에 의존하는 상황이 있습니다. 앞으로 선언문을 작성했지만 문제가 계속 발생합니다.불완전한 유형을 컴파일하지 못했습니다. 순환 의존성

In file included from src/MemoWriteContext.h:7:0, 
        from src/MemoWriteContext.cpp:1: 
src/MemoContext.h:29:20: error: field ‘memoWriteContext’ has incomplete type 

MemoContext.h

#ifndef MEMOCONTEXT_H_ 
#define MEMOCONTEXT_H_ 

#include "sqlite/SqliteDb.h" 
#include "Context.h" 
#include "MemoWriteContext.h" 

#include <string> 
#include <memory> 
#include <map> 

namespace bbs 
{ 
    class MemoWriteContext; 

    class MemoContext : public Context 
    { 
    public: 
     //'structors 
     MemoContext(const std::map<std::string, std::shared_ptr<Context> > &_contexts, 
        sqlitecpp::SqliteDb &_sqliteDb); 
     ~MemoContext(); 

    protected: 
     //when called write the data back to the user 
     void performAction(const std::string &data, std::shared_ptr<UserAgent> agent); 

    private: 
     MemoWriteContext memoWriteContext; 
    }; //class memocontext 
} 

#endif // MEMOCONTEXT_H_ 

MemoWriteContext.h

#ifndef MEMOWRITECONTEXT_H_ 
#define MEMOWRITECONTEXT_H_ 

#include "Context.h" 
#include "sqlite/SqliteDb.h" 
#include "sqlite/PreparedStmt.h" 
#include "MemoContext.h" 

#include <string> 
#include <memory> 
#include <map> 

namespace bbs 
{ 
    class MemoContext; //forward decl 

    class MemoWriteContext : public Context 
    { 
    public: 
     //'structors 
     MemoWriteContext(const std::map<std::string, std::shared_ptr<Context> > &_contexts, 
         MemoContext &_memoContext, sqlitecpp::SqliteDb &_sqliteDb); 
     ~MemoWriteContext(); 

    protected: 
     //when called write the data back to the user 
     virtual void performAction(const std::string &data, std::shared_ptr<UserAgent> agent); 
     virtual void onReceiveUserAgent(std::shared_ptr<UserAgent> agent); 
    private: 
     MemoContext &memoContext; //parent; 
     sqlitecpp::SqliteDb &sqliteDb; 
     sqlitecpp::PreparedStmt writeMemoStmt; 
     sqlitecpp::PreparedStmt findAgentIdStmt;  
    }; 

    enum class MemoWriteState : char 
    { 
     USERNAME=0, 
     MESSAGE, 
     CONFIRM 
    }; 

    class MemoWriteAgentData : public ContextAgentData 
    { 
    public: 
     MemoWriteState state; 
     int userId; 
     std::string message;  
    }; //class Memo Write Agent data 

} 

#endif // MEMOWRITECONTEXT_H_ 

Full source here.

+0

이 질문은 C++과는 아무런 관련이 없습니다. 0x –

답변

3

유일한 문제는 MemoWriteContext.h#include "MemoContext.h"이 있다고 생각합니다. 컨텍스트에는 forward 선언을 사용할 수있는 참조 만 필요합니다. 하지만 MemoWriteContext.h첫 번째을 포함하는 경우 앞에이 실제로는 class MemoWriteContext이라고 표시됩니다. 그러면 앞으로 선언문 인 class MemoWriteContext이 사용되며 실패합니다. 오류 메시지에서 주문을 볼 수도 있습니다.

#include을 제거하거나 적어도 MemoWriteContext.cpp에있는 포함 순서를 뒤집으십시오 (각 .h이 포함되어 있기 때문에 다른 쪽을 효과적으로 뒤집을 수 있음).

+0

이것은 완벽하게 작동했습니다. 이제 컴파일되고 스택 의미를 유지하게됩니다. 고맙습니다 – 111111

1

이 :

class MemoWriteContext; 

전달 선언입니다. 이것은 "불완전 유형"이므로 인스턴스화 할 수 없습니다.

왜냐하면 C++ 컴파일러는 인스턴스화해야하는 모든 유형의 크기를 알아야하기 때문입니다. 불완전한 유형에는 크기가 없습니다. 당신이 실제로 포인터를 선언하기 때문에

MemoWriteContext * ptr; 

, 포인터 알려진 크기가 :

그런데

, 당신은이 작업을 수행 할 수 있습니다.

동적 할당을 피하려면 MemoWriteContext.h을 포함하고 전달 선언을 제거하여 유형을 완전히 선언해야합니다.

+0

그래,하지만 가능한 한 스택에 원하는 다른 유형의 포인터를 원하지 않습니다. 이 문제를 해결할 다른 방법이 있습니까? – 111111

+0

각 사용자는 다른 사용자의 헤더에 액세스 할 수 있습니다. 난 전향 십자가를 cirular 의존성 주위에 얻을 수있는 입찰가에 넣어 있지만이 해결되지 않았습니다. 우리가 전혀 도움이된다면 동적 메모리를 사용하지 않는 편이 낫습니다. 감사합니다. – 111111

관련 문제