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.
精彩评论