简体   繁体   English

具有不完整类型和unique_ptr的树结构

[英]Tree structure with incomplete types and unique_ptr

I have quick question regarding incomplete types and unique_ptr. 关于不完整的类型和unique_ptr,我有一个快速的问题。 I was trying to have a simple tree kinda structure which has been simplified here and I was getting a few compiler errors about incomplete types and what I knew was that I have to define the dtor which makes. 我试图建立一个简单的树样结构,在这里已对其进行了简化,并且遇到了一些关于不完整类型的编译器错误,并且我知道我必须定义生成的dtor。 Though that did not solve the issue, at least in msvc that I am testing it. 虽然那不能解决问题,但至少在msvc中,我正在测试它。

What I instead had to do was that for every class that required destruction of the incomplete types I had to just include the relevant header in the .cpp file. 相反,我要做的是对于每个需要销毁不完整类型的类,我只需要在.cpp文件中包含相关标头即可。 Defining explicitly the dtor did not help which was surprising to me. 明确定义dtor并没有帮助,这令我感到惊讶。

Level1.h 1级

#include "Level2Vector.h"

class Level1
{
public:
    Level1() : lvl2_vec(this) {}

private:
    Level2Vector lvl2_vec;
};

Level1.cpp Level1.cpp

#include "Level2.h" // this was needed to not get the incomplete type
#include "Level3.h" // this was needed to not get the incomplete type 

Level2.h Level2.h

#include "Level3Vector.h"

class Level1;

class Level2
{
public:
    Level2(Level1* const lvl1) : parent_(lvl1), lvl3_vec(this){}

private:
    Level1* parent_;
    Level3Vector lvl3_vec;
};

Level2.cpp Level2.cpp

#include "Level2.h"
#include "Level3.h"  // this was needed to not get the incomplete type

Level3.h 3级

class Level2;

class Level3
{
public:
    Level3(Level2* const lvl2) : parent_(lvl2) {}

private:
    Level2* parent_;
};

Level2Vector.h Level2Vector.h

class Level1;
class Level2;

class Level2Vector : public std::vector<std::unique_ptr<Level2>>
{
public:
    Level2Vector(Level1* lvl1) : parent_(lvl1) {}

private:
    Level1* parent_;
};

Level3Vector.h Level3Vector.h

class Level2;
class Level3;

class Level3Vector : public std::vector<std::unique_ptr<Level3>>

{
public:
    Level3Vector(Level2* lvl2) : parent_(lvl2) {}
    //~Level3Vector();

private:
    Level2* parent_;
};

Am I missing something ? 我想念什么吗? Is every class that would potentially be using say Level2Vector need to include the Level2.h header ? 是否每个可能使用的类都说Level2Vector需要包括Level2.h标头?

The type should be complete for the destructor, but the destructor is auto generated inline, so that mean that each place where the class is destroyed should have definition of the class own by std::unique_ptr . 该类型对于析构函数应该是完整的,但是该析构函数是自动内联生成的,因此,意味着销毁该类的每个位置都应具有std::unique_ptr拥有的该类的定义。

The simpler to avoid this problem is to declare destructor for each class that have std::unique_ptr member. 避免此问题的更简单方法是为每个具有std::unique_ptr成员的类声明析构函数。 So: 所以:

class Level3Vector
{
public:
    explicit Level3Vector(Level2* lvl2) : parent_(lvl2) {}
    ~Level3Vector();

    // And so rule of 5
    Level3Vector(const Level3Vector&) = delete;
    Level3Vector& operator =(const Level3Vector&) = delete;

    Level3Vector(Level3Vector&&) = default;
    Level3Vector& operator =(Level3Vector&&) = default;

private:
    std::vector<std::unique_ptr<Level3>> lvl3s;
    Level2* parent; // or std::observer_ptr<Level2> parent;
};

And in cpp: 在cpp中:

#include <Level3.h>

Level3Vector::~Level3Vector() = default;

Then destruction of Level3Vector in other classes doesn't require the include of <Level3.h> . 然后在其他类中销毁Level3Vector不需要包含<Level3.h>

Generally speaking, you may use a forward-declared type (say in a header file you define a pointer using that type); 一般来说,您可以使用前向声明的类型(例如,在头文件中,您使用该类型定义指针); but the definition of the type must be available before the definition of the type is needed. 但是在需要定义类型之前,必须先提供类型的定义。 Eg in Level1.h you define an object of type Level2Vector (not a pointer to Level2Vector!); 例如,在Level1.h中,您定义了Level2Vector类型的对象(而不是Level2Vector的指针!); so Level1.h must include Level2Vector.h. 因此,Level1.h必须包含Level2Vector.h。

With that in mind, let's examine your question "Does every class that would potentially be using Level2Vector need to include the Level2.h header?" 考虑到这一点,让我们检查一下您的问题“可能使用Level2Vector的每个类都需要包括Level2.h标头吗?” The answer is no. 答案是不。 Level2.h provides the definition of class Level2. Level2.h提供了类Level2的定义。 So the correct way to look at it is: a file (using Level2Vector or not) needs to include Level2.h, if the file needs the definition of Level2. 因此,正确的查看方法是:如果文件需要使用Level2的定义,则该文件(是否使用Level2Vector)需要包含Level2.h。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM