2011-07-05 35 views
2

您好在編譯代碼時遇到問題,我有一個情況,A依賴於B,而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"。上下文只需要一個可以使用前向聲明的引用。但是,如果您碰巧包含MemoWriteContext.h第一個,它會在之前帶上MemoContext.h它實際上會聲明class MemoWriteContext。然後這將使用class MemoWriteContext的前向聲明並失敗。您甚至可以在錯誤消息中看到排序。

只要刪除那#include或至少扭轉MemoWriteContext.cpp包括(包括其他.h包括其他有效地反轉回它們)的順序。

+0

這工作完美,現在編譯,我得到保持堆棧語義。謝謝 – 111111

1

此:

class MemoWriteContext; 

是前向聲明。這是一個「不完整的類型」,因此不能實例化。

原因是C++編譯器必須知道必須實例化的任何類型的大小。不完整的類型沒有大小。

順便說一句,你可以這樣做:

MemoWriteContext * ptr; 

因爲你實際上聲明指針和指針具有已知大小。

如果你想避免動態分配,那麼你必須通過包括MemoWriteContext.h和刪除前向聲明來完全聲明該類型。

+0

是的,但我真的不想要一個指向其他類型的指針,我只是希望它在堆棧上,如果可能的話。有沒有其他的方法呢? – 111111

+0

每個人都可以訪問其他標題。我已經提出了前瞻性的十一月,以解決這個問題,但是這並沒有解決它。如果我們完全可以幫助它,我真的不希望用於動態內存。謝謝 – 111111