开发者

Failure to compile incomplete types; circular dependencies

Hi am having problems compiling some code, I have a situation where A depends and B depends on A. I have put forward declarations but I keep getting the problems.

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
        v开发者_如何学Pythonoid 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.


I think your only problem is that MemoWriteContext.h has #include "MemoContext.h". The context only requires a reference which can use the forward declaration. But if you happen to include MemoWriteContext.h first it will then bring in MemoContext.h before it actually declares class MemoWriteContext. That will then use the forward declaration of class MemoWriteContext and fail. You can even see the ordering in your error message.

Just remove that #include or at least reverse the order of the includes in MemoWriteContext.cpp (since each .h including the other effectively reverses them back).


This:

class MemoWriteContext;

Is a forward declaration. It's an "incomplete type", and therefore cannot be instantiated.

The reason is that a C++ compiler must know the size of any type that has to be instantiated. Incomplete types have no size.

By the way, you can do this:

MemoWriteContext * ptr;

Because you actually declare a pointer, and pointers have a known size.

If you want to avoid dynamic allocations, then you'll have to fully declare the type by including MemoWriteContext.h and removing the forward declaration.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜