2012-12-05 173 views
6

我需要設置一個類繼承結構,其中抽象基類只保存成員變量(但不包含成員方法)。成員方法將由派生類定義。因此,我需要的是這篇文章:Making a class abstract without any pure virtual methods受保護的構造函數與純虛析構函數

從頂部的2答案在那裏,我意識到有2種方式實現它:

  • 讓析構函數純虛。
  • 使構造函數受到保護。

我很想知道兩種方法之間的區別。是否有一種情況應該比另一種更優先(或者某些特殊情況下可以工作而不是另一種)?我想了想,想不到任何事情。

我在這裏搜索了一些帖子的答案(Is there a use for making a protected destructor virtual?,C++: Protected Class Constructor,Should an abstract class' destructor be pure virtual?),試圖把東西放在一起,但我無法得出結論。

回答

3

的主要區別是在

Base * ptr = new Derived; 
delete ptr; 

隨着虛擬析構它是合法的,沒有它會有UB。另外dynamic_cast需要至少一個虛擬功能。
所以,如果你想要多態的行爲,使用(純)虛擬析構函數。如果你不需要它,使用受保護的構造函數,不要爲多態性(vtables)支付開銷。但是然後聲明析構函數也受到保護,以防止通過基指針進行刪除。

+1

這不*真的*回答OP的問題。一個非純粹的虛擬析構函數可以與受保護的構造函數一起使用,而您的示例代碼將顯示已定義的行爲。你在談論一個相關但正交的問題。 –

3

這兩種方式都通過利用完全不同的機制來達到預期的效果。在我看來,protected constructor更具表現力,因爲它完全對應於您的問題描述。 Pure virtual destructor不是一個自然的解決方案,可能需要額外的文檔來解釋其目的。它也會強制子類實現析構函數,即使它可能被跳過。

+0

我讀過,如果你沒有在派生類中顯式實現析構函數,那麼爲它們自動生成的就足夠了。所以純虛析構函數不會強制子類實現它們的析構函數。 – Wutz

+0

@Wutz,那麼目的是什麼? –

+0

@Michael Krelin - 黑客:在沒有純虛擬方法的情況下製作基類抽象。允許基類爲其虛擬方法定義默認實現並仍然阻止它被直接實例化是非常有用的。 – Wutz

相關問題