我有关于不完整类型和unique_ptr的快速问题。 我试图有一个简单的树类型结构,这里已经简化了,我得到了一些关于不完整类型的编译器错误,我知道我必须定义dtor。虽然这没有解决问题,至少在msvc我正在测试它。
我需要做的是,对于每个需要销毁不完整类型的类,我必须在.cpp文件中包含相关的标题。明确定义dtor并没有帮助,这让我感到惊讶。
Level1.h
#include "Level2Vector.h"
class Level1
{
public:
Level1() : lvl2_vec(this) {}
private:
Level2Vector lvl2_vec;
};
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
#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
#include "Level2.h"
#include "Level3.h" // this was needed to not get the incomplete type
Level3.h
class Level2;
class Level3
{
public:
Level3(Level2* const lvl2) : parent_(lvl2) {}
private:
Level2* parent_;
};
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
class Level2;
class Level3;
class Level3Vector : public std::vector<std::unique_ptr<Level3>>
{
public:
Level3Vector(Level2* lvl2) : parent_(lvl2) {}
//~Level3Vector();
private:
Level2* parent_;
};
我错过了什么吗? 是否每个可能使用的类都说Level2Vector需要包含Level2.h标题?
答案 0 :(得分:1)
析构函数的类型应该是完整的,但是析构函数是内联自动生成的,这意味着销毁类的每个地方都应该通过std::unique_ptr
定义类所拥有的。
避免此问题的简单方法是为每个具有std::unique_ptr
成员的类声明析构函数。所以:
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;
};
在cpp:
#include <Level3.h>
Level3Vector::~Level3Vector() = default;
然后在其他类中销毁Level3Vector
不需要包含<Level3.h>
。
答案 1 :(得分:0)
一般来说,您可以使用前向声明的类型(例如在头文件中使用该类型定义指针);但是在需要定义类型之前,必须提供类型的定义。例如。在Level1.h中,您定义了Level2Vector类型的对象(不是指向Level2Vector的指针!);所以Level1.h必须包含Level2Vector.h。
考虑到这一点,让我们检查你的问题&#34;每个可能使用Level2Vector的类是否需要包含Level2.h标题?&#34;答案是不。 Level2.h提供了Level2类的定义。因此,查看它的正确方法是:如果文件需要Level2的定义,则文件(使用Level2Vector或不使用Level2.h)需要包含Level2.h。