2013-10-30 26 views
1

最近我一直在提出以下問題:從類防止被instanstiated

你寫了一個基類,你希望其他人能夠從供其個人使用派生。你希望沒有人能夠實例化你正在編寫的基類(只有派生類的對象)。 你將如何實施課程?

我已經想到兩種解決方案:

一體,是使基類抽象(通過添加純虛函數)。

其次,將構造函數置於受保護的部分下,因此從外部無人能夠創建它的實例,只有派生類。

我的問題是,我的解決方案(在所有方面你可以想到)有什麼區別?

謝謝。

回答

3

一個受保護的構造是明智的,但並不能阻止類被實例化:

class Foo 
{ 
protected: 
    Foo() = default; 
public: 
    static Foo make() { return Foo(); } 
}; 

int main() 
{ 
    auto f = Foo::make(); 
} 

在另一方面,抽象類不能被實例化,這是你可能想要的這裏。

但是,重要的問題是您是否確實需要多態性層次結構,您需要在運行時決定類型並通過基本指針處理異構對象集合。如果是這樣,那麼抽象的基礎就是它的走向。如果沒有,你就不能擁有一個沒有虛函數的抽象類,而受保護的構造函數(和析構函數)是唯一的方法來表明你想要一個不合理的基礎。

+0

我認爲一個'protected'構造函數足以阻止這個類被實例化。你通過添加一個靜態成員函數來返回一個實例來「輕微地」作弊。即使是作弊,一個'protected'或'private'拷貝構造函數也會阻止你。 –

+0

@NikBougalis:我還可以有一個靜態函數返回一個'新Foo' - 不需要複製:-S –

+0

沒錯 - 但問題是如果你要作弊,那麼遊戲就結束了。但是你確實強調了一個私有構造函數是不夠的,它與基類中的純虛函數有什麼不同,以防止實例化。 –

2

純虛函數將虛函數表的開銷添加到您的基類中,如果您需要保持對象非常小,這可能是一個問題。這種開銷可以通過使用受保護的構造函數和/或受保護的析構函數來避免。受保護的析構函數有助於防止通過基類指針進行命令刪除,而在沒有虛擬析構函數的情況下,該指針會導致未定義的行爲。