2012-12-04 27 views
1

以下代碼將導致C4624。但是你可以看到D不是B的子類。爲什麼仍然有這個警告?謝謝!當使用組合而不是繼承時,爲什麼我得到C4624(基類析構函數無法訪問)?

class B { 
// Uncomment the following line to resolve. 
// public: 
~B(); 
}; 

class D {B b;}; // C4624 B's destructor not public 

有關警告的詳細信息:

C4624:「派生類」:未能生成析構函數,因爲一個基類的析構函數是不可訪問

析構函數是不是在一個基類訪問,因此不是爲派生類生成的。任何嘗試在堆棧上創建此類型的對象都會導致編譯器錯誤。

+9

錯誤消息似乎是錯誤的,但如果忽略「基類」部分,錯誤是合法的。 –

+1

爲什麼你不想公開B的析構函數? –

+0

我知道這是不正確的,我不想這樣做。我只是想在這裏發佈:http://stackoverflow.com/a/13576544/304115 po – fresky

回答

1

類成員由類的構造函數初始化並由其析構函數銷燬。因此它們的構造函數和析構函數必須在這些函數中可訪問。

在你的榜樣,B擁有一個私人的析構函數,因此是不的D析構函數,這需要它摧毀B類型它的成員訪問。

我不知道爲什麼錯誤信息引用了「基類」。如果您從發佈的代碼中獲得錯誤消息,那麼編譯器可以對其診斷進行一些改進。

+0

我在Visual Studio 2012中得到了這個警告。我只是想知道爲什麼警告說「基類」。 – fresky

+0

最有可能的是,編譯器編寫器重用錯誤代碼而不檢查它是否適合其新上下文。這是一個常見的錯誤,[可能非常昂貴](http://archive.eiffel.com/doc/manuals/technology/contract/ariane/)。 –

0

因爲類DB類和B類的朋友是不是D類的一部分。這意味着B的私密部分無法從D的範圍訪問。這也意味着您不能在堆棧上創建DB類型的對象,因爲當對象超出範圍並且應該刪除時,它將要求B的析構函數可訪問。請注意,錯誤消息似乎不正確,正如@ R.MartinhoFernandes所提及的那樣。如果您自己管理內存,則可以使用私有析構函數(like described here)。

相關問題