【问题标题】:Member acces into incomplete type C++成员访问不完整类型 C++
【发布时间】:2021-11-18 13:37:26
【问题描述】:

我正在尝试在 C++ 中创建两个类 - class1、class2。我希望 class2 包含 class1 的实例,并且 class1 具有指向 class2 的 shared_ptr - 指向包含它的对象的指针。 所以我有以下 4 个文件:

class2.hpp

#include "class1.hpp"
#include <vector>

class class2 {
    friend class1;
private:
    class1 data;
    std::vector<int> numbers;
public:
    class2();
};

class2.cpp

#include "class2.hpp"

class2::class2() : data(std::shared_ptr<class2>(this)){}

class1.hpp

#include <memory>

class class2;
class class1 {
    std::shared_ptr<class2> ptr;
    class1(std::shared_ptr<class2> ptr);
    void add_item(int i);
};

和class1.cpp

#include "class1.hpp"

class1::class1(std::shared_ptr<class2> ptr) {
    ptr = ptr;
}

void class1::add_item(int i) {
    ptr->add_item(6); //Member access into incomplete type 'std::__1::shared_ptr<class2>::element_type' (aka 'class2')
}

我在函数 add_item 中遇到错误。我认为这与class2的前向声明有关。 我找到了这个相关主题,但他们没有将文件拆分为头文件。 error: member access into incomplete type : forward declaration of

如果我理解得很好,我应该把函数 add_item 放在 class2 的定义之后,但我不知道如何解决它,如果我想像这样拆分文件。可能吗? 请注意,我正在尝试在更大的项目中解决这个问题,这非常简单。

感谢您的任何回答。

【问题讨论】:

  • 避免在您的 .hpp 文件中使用任何 #include(使用前向声明)。并将您的#includes 放入 cpp 文件中
  • 你忘了包含class2.hpp,一个简单的错字。
  • class1.cpp 应包括 class2.hppclass1.hpp 不应包含 class2.hpp
  • “我应该把函数 add_item 放在 class2 的定义之后” -- 对。确实如此,但从一个翻转的角度来看。您应该将class2 的定义放在add_item 的定义之前。那么问题应该变成你如何将class2的定义放在class1.cpp的开头?
  • std::shared_ptr&lt;class2&gt;(this) 是绝对不允许的 - 你不能将 *this 的所有权移交给 shared_ptr - 它确实有所有者。

标签: c++ forward-declaration


【解决方案1】:

在 class2.hpp 中转发声明 class1 并在 class1.cpp 中包含 class2.h。

class2.hpp:

//#include "class1.hpp"       // REMOVE!
#include <vector>

class class1;                 // ADD
class class2 {
...

class2.cpp:

#include "class2.hpp"
#include "class1.hpp"         // ADD

class1.hpp:

#include <memory>

class class2;                // OK

class1.cpp:

#include "class1.hpp"
#include "class2.hpp"         // ADD

class1::class1(std::shared_ptr<class2> ptr) {
    ptr = ptr;
}

【讨论】:

    【解决方案2】:

    我希望 class2 包含 class1 的实例,并且 class1 具有指向 class2 的 shared_ptr - 指向包含它的对象的指针。

    不,你不应该这样。子对象没有理由拥有(即使是共享容量)它们的超级对象。

    此外,您不能访问不完整类的成员。您必须先定义类。

    【讨论】:

    • 谢谢。但是如果它们在单独的文件中,我如何首先定义类呢?
    • @TobyV。包括定义类的标题。为此目的有一个预处理器指令。
    猜你喜欢
    • 2021-11-13
    • 1970-01-01
    • 2016-05-27
    • 1970-01-01
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-20
    相关资源
    最近更新 更多