簡體   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