2014-12-06 54 views
10

說我有兩類:的unique_ptr和前瞻性聲明

「foo.h中」

#pragma once  
class Foo 
{ 
public: 
    Foo() 
    { 

    }; 

    ~Foo() 
    { 

    }; 
}; 

「A.H」

#pragma once 
#include <memory> 

class Foo; 

class A 
{ 
public: 
    A(){}; 
    ~A(){}; 

    std::unique_ptr<Foo> foo; 
}; 

A持有的Foo一個unique_ptr。我不想在「A.h」中包含Foo,所以我向前宣佈了它。通過只向前聲明類Foo在「啊」,我得到一個編譯時錯誤:

error C2027: use of undefined type 'Foo' 
error C2338: can't delete an incomplete type 

所以我下面就如何避免這個錯誤this文章,並在它自己的.cpp文件,我搬到A的析構函數還包括富:

「A.cpp」

#include "A.h" 

#include "Foo.h" 

A::A() 
{ 

} 

A::~A() 
{ 

} 

在「A.cpp」實施的析構函數後,我能夠編譯程序,因爲Foo類是已知「 A.cpp」。這似乎是合乎邏輯的,因爲unique_ptr需要完整的類型來調用它的析構函數。但令我驚訝的是,在評論完A的構造函數(在「A.h」以及「A.cpp」)後,我得到了同樣的錯誤。這怎麼可能?當A沒有構造函數時,爲什麼編譯器會抱怨不能調用Foo的析構函數?

編輯: 我上傳了4個文件,以便測試該程序。 我使用MSVC++的Visual Studio 2013年

http://www.filedropper.com/test_61

+5

'A'確實有一個構造函數,當你註釋掉你constructo r:編譯器提供了一個默認的構造函數,這個構造函數獲得了一個內聯定義。 – dyp 2014-12-06 21:32:46

+0

是的,但使用標準構造函數,我得到編譯器錯誤,他無法刪除完整類型。在編寫我自己的空構造函數時,它應該看起來像默認的那樣,我不會看到這些編譯錯誤。 – abcheudg234 2014-12-06 21:40:29

+0

向我們展示不起作用的代碼? – 2014-12-06 21:44:44

回答

-1

的是沒有可能的 'A' 不具有構造函數。

如果您評論了您編寫的構造函數,編譯器將爲您創建一個默認構造函數,它不一定與您定義的構造函數在同一個位置。造成了這個問題。

+1

但是爲什麼我必須在A.cpp中定義構造函數呢?我明白,編譯器抱怨說,A的析構函數必須在Foo.h被包含的地方定義 - 這是一個完整的類型,A的析構函數實際上可以破壞Foo。但我不明白爲什麼A的CONstructor也必須在A.cpp中定義。您可以通過複製類並在main()中實例化A來嘗試代碼。當註釋掉A的構造函數時,代碼將不會編譯。 – abcheudg234 2014-12-06 21:59:11

+3

你要起訴哪個編譯器? – 2014-12-06 22:02:49

+1

我正在使用Visual Studio 2013的MSVC++編譯器。 – abcheudg234 2014-12-06 22:06:41

14

的構造需要用同樣的方法獲得了缺失者的析構函數所做的:異常安全要求的構造能夠回滾的情況下,所有的成員,你的構造函數的身體拋出的初始化:

[C++14: 12.6.2/10]: In a non-delegating constructor, the destructor for each potentially constructed subobject of class type is potentially invoked (12.4). [ Note: This provision ensures that destructors can be called for fully-constructed sub-objects in case an exception is thrown (15.2). —end note ]

相關: