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

发布于 2024-11-18 09:14:09 字数 2732 浏览 2 评论 0原文

您好,我在编译一些代码时遇到问题,我遇到了 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_

完整源代码在这里。

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
        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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼藏柔 2024-11-25 09:14:09

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

只需删除该 #include 或至少颠倒 MemoWriteContext.cpp 中包含的顺序(因为每个包含另一个的 .h 都有效地颠倒了它们)后退)。

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).

凉宸 2024-11-25 09:14:09

class MemoWriteContext;

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

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

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

MemoWriteContext * ptr;

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文