无法编译不完整的类型;循环依赖

时间:2011-07-05 20:11:14

标签: c++ g++ circular-dependency

您在编译某些代码时遇到问题,我有一种情况,其中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.

2 个答案:

答案 0 :(得分:3)

我认为您唯一的问题是MemoWriteContext.h#include "MemoContext.h"。上下文只需要一个可以使用前向声明的引用。但是,如果您碰巧先包含MemoWriteContext.h ,那么它会在之前引入MemoContext.h ,它实际上会声明class MemoWriteContext。那将使用class MemoWriteContext的前向声明并失败。您甚至可以在错误消息中看到排序。

只需删除#include或至少颠倒MemoWriteContext.cpp中包含的顺序(因为每个.h包括另一个有效地将它们反转回来)。

答案 1 :(得分:1)

此:

class MemoWriteContext;

是前瞻声明。它是一个“不完整类型”,因此无法实例化。

原因是C ++编译器必须知道必须实例化的任何类型的大小。不完整的类型没有大小。

顺便说一句,你可以这样做:

MemoWriteContext * ptr;

因为你实际上声明了一个指针,并且指针的大小已知。

如果您想避免动态分配,那么您必须通过包含MemoWriteContext.h并删除前向声明来完全声明类型。