2012-08-13 21 views
2

我使用boost::scoped_ptr並在頭文件中預先聲明:什麼翻譯單位持有隱含定義的特殊成員函數?

//Bar.h 
class Foo; 

class Bar; 
{ 

private: 
    boost::scoped_ptr<Foo> _foo; 
}; 

我沒有實現我自己的析構函數,因爲智能指針將做的工作。

我將這個頭文件包含在多個翻譯單元中,並不是所有的都包含Foo定義。當試圖編譯時,我得到一個錯誤,scoped_ptr正在刪除一個指針,指向不完整類型Foo

如果我在Bar.h中聲明空的析構函數並在Bar.cpp中實現它,一切都很容易修復。

但是,如果析構函數是在頭文件中實現的,我得到了同樣的錯誤。

所以問題是:在哪個翻譯單元做隱式定義的方法去?

+0

@DavidRodríguez-dribeas:謝謝,我選擇了你的配方 – Andrew 2012-08-13 13:20:28

+0

由於同樣的原因,我編輯了最後一句話。還刪除了對* default構造函數/析構函數*的引用。在C++中,默認構造函數是不帶參數的構造函數,無論它是否被隱式定義。 – 2012-08-13 13:22:15

+0

@DavidRodríguez-dribeas:是的,你說得對,謝謝 – Andrew 2012-08-13 13:23:54

回答

4

這個問題沒有正確的表述。你想知道什麼是

什麼翻譯單位持有暗含定義的特殊成員函數?

[這是一口]。答案是在每個翻譯單元中,使用(odr-uses)它們。

爲您的特定的使用情況,而且由於scoped_ptr析構函數需要的類型是完整的,你別無選擇,只能申報Bar析構函數,即使空在具有的完整定義,翻譯單元定義它Foo

或者,您可以使用不具有該限制的不同類型的智能指針。

4

所以問題是:在哪個翻譯單元中實現了頭部實現的方法?

在所有這些。也就是說,每個TU都有自己的(內聯)實現。

你會在這裏得到錯誤,因爲顯然析構函數需要定義Foo。這與無關,其中的析構函數已定義。如果您將其定義在自己的TU中,則該TU仍然需要知道Foo的定義。

+0

感謝您的回答!但是,鏈接器如何解決同一個函數的多個定義呢? – Andrew 2012-08-13 13:16:26

+1

@Andrew:*隱式定義的特殊成員函數*是'inline'。鏈接器解決了與其他任何'inline'函數一樣的問題,通過選擇其中一個定義並丟棄其餘部分(這是一個實現細節,可以完成其他事情,但這就是我知道的每個鏈接器的行爲方式) – 2012-08-13 13:17:53

相關問題