繁体   English   中英

std :: vector的不完整类型

[英]Incomplete type for std::vector

当我尝试以下操作时,GCC编译器会抱怨(见下文)。 class Face需要不完整,因为它包含指向class Element指针,类似于包含class Face指针。 换句话说,类之间存在循环依赖关系。 我该如何解决?

错误:'sizeof'无效应用于不完整类型'Face'

class Face; // needs to be incomplete

class Element
{
    std::vector < std::unique_ptr <Face> > face;
};

class Face
{
    std::vector < std::unique_ptr <Element> > elm;
};

解决这个问题的一种方法是声明Element和Face的析构函数和构造函数,但不在头文件中定义它们。 然后你需要在cpp文件中定义它们。

(更多技术细节可以在我的问题的答案中找到: std :: unique_ptr <T>是否需要知道T的完整定义?

问题的根源是unique_ptr的析构函数需要调用delete (默认情况下),因此它需要知道类型的定义(具有它的大小)。 但是如果Element和Face的析构函数是自动生成的,那么它将默认内联:使用Element和Face实例的代码将被强制知道两种类型的大小,以便它们的析构函数可以调用unique_ptr析构函数,该析构函数可以调用delete与指针关联的类型。

我给出的解决方案将确保unique_ptr的构造和销毁在单独的cpp中是不确定的。 它们不会被内联,但仍可使用Element和Face通过代码调用它们。 unique_ptrs的析构函数代码将位于cpp中,其中定义了Element和Face的析构函数,因此在这些cpp中将需要两者的定义。

举个例子:

//header
class Face; // needs to be incomplete

class Element
{
public:
    Element(); // don't define it here
    ~Element(); // don't define it here
private:
    std::vector < std::unique_ptr <Face> > face;
};

class Face
{
public:
    Face(); // don't define it here
    ~Face(); // don't define it here
private:
    std::vector < std::unique_ptr <Element> > elm;
};

// cpp 
#include "header"
// if you want the default impl (C++11)
Element::Element() = default; 
Element::~Element() = default; 

Face::Face() = default; 
Face::~Face() = default; 

如果它们位于不同的header / cpp对中,它仍然是相同的解决方案。 但是,您必须执行更多的前向声明,并且定义构造/销毁的cpp文件必须包含所有必需的头:

//element.h
class Face; // needs to be incomplete

class Element
{
public:
    Element(); // don't define it here
    ~Element(); // don't define it here
private:
    std::vector < std::unique_ptr <Face> > face;
};

////////////////////////////////////////////////////////////
// face.h
class Element; // needs to be incomplete

class Face
{
public:
    Face(); // don't define it here
    ~Face(); // don't define it here
private:
    std::vector < std::unique_ptr <Element> > elm;
};

////////////////////////////////////////////////////////////
// element.cpp 
#include "element.h"
#include "face.h" // necessary to allow the unique_ptr destructor to call delete

// if you want the default impl (C++11)
Element::Element() = default; 
Element::~Element() = default; 

////////////////////////////////////////////////////////////
// face.cpp 
#include "element.h" // necessary to allow the unique_ptr destructor to call delete
#include "face.h" 

// if you want the default impl (C++11)
Face::Face() = default; 
Face::~Face() = default; 

暂无
暂无

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

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