2014-01-31 99 views
1

如果已經提問此問題,我表示抱歉。我正在寫一個將與python接口的C++類。到目前爲止的類實現是:非多態和非抽象基類中的虛析構函數

struct body_data 
{ 
map <int, atom*> atoms; 
map <int, bond*> bonds; 
map <int, dihedral*> dihedrals; 
}; 

該類是另一個類的基類。我沒有添加這個類的析構函數,因爲我很困惑。在所有我已經讀過關於基類的析構函數的文章中,他們建議析構函數應該是公共虛擬的或者是保護的。由於我不打算在C++代碼或python接口中多態地使用上述類,我是否真的需要使析構函數爲public virtual或protected?我正在考慮讓這個類公開,這樣程序員就會知道永遠不會多態地使用這個類。我的想法是否正確?

+0

創建3個課程。上面有一個受保護的析構函數,一個從上面繼承而來的類,沒有其他變化(但沒有繼承),還有第三個類繼承了上面的類,並做了其他的工作。這意味着如果有人刪除了一個指向base的指針,他們將得到一個錯誤:這是好的,因爲有兩個不同的類是有效的基指針,並且將它們刪除錯誤是未定義的行爲。 – Yakk

回答

2

您只有需要公共析構函數在您有虛函數時聲明爲虛函數,表示您打算從中派生類型。我強調「需要」,因爲只有當您的基本類型具有非POD類型時才需要您知道從您派生的類型將具有非POD類型。是的,你可以擁有一個虛擬成員爲零的基類,但是這樣的基礎具有邊際效用。不必要地添加虛擬成員會增加開銷。即如果你有一個沒有虛擬析構函數以外的虛擬成員的類型,通常你增加了一個指針的每個實例的大小,並且所述對象的銷燬會稍微慢一點,因爲你必須至少調用析構函數單個內存間接。在第一個虛擬成員之後增加虛擬成員應該有固定的內存開銷,但是你仍然會因爲不必要的虛擬化功能而導致運行時懲罰。

在你的情況下,你的數據類型似乎表明了動態分配的內存(其值是原始指針的映射)的所有權,並且你已經指出這是用作其他類型的基礎(這是關鍵),在這種情況下,你肯定會想要定義一個析構函數來正確釋放內存,並且既然你已經聲明它是其他類型的基礎,它應該被標記爲虛擬的,除非你能絕對確保這些實例永遠不會被銷燬除了指向最派生類型的指針之外的任何東西(作出這種假設是非常危險的並且失敗可能導致難以診斷內存泄漏)。

+0

我正在用C++編寫代碼,而不是使用cython將代碼編譯爲python模塊。如果C++和cython代碼總是使用代碼當前正在發送的派生類型。我可以假設python用戶將無法使用基指針訪問派生類型嗎? –

+0

我將它用作基類的原因是因爲我有大約3到4個派生類,它們都使用body_data類中的成員。 –

+1

@ZacharyKraus,僅僅因爲他們使用* body_data類並不意味着他們應該從它派生*。你有沒有想過讓它成爲每個人的成員? –

相關問題