最近我一直在提出以下問題:從類防止被instanstiated
你寫了一個基類,你希望其他人能夠從供其個人使用派生。你希望沒有人能夠實例化你正在編寫的基類(只有派生類的對象)。 你將如何實施課程?
我已經想到兩種解決方案:
一體,是使基類抽象(通過添加純虛函數)。
其次,將構造函數置於受保護的部分下,因此從外部無人能夠創建它的實例,只有派生類。
我的問題是,我的解決方案(在所有方面你可以想到)有什麼區別?
謝謝。
最近我一直在提出以下問題:從類防止被instanstiated
你寫了一個基類,你希望其他人能夠從供其個人使用派生。你希望沒有人能夠實例化你正在編寫的基類(只有派生類的對象)。 你將如何實施課程?
我已經想到兩種解決方案:
一體,是使基類抽象(通過添加純虛函數)。
其次,將構造函數置於受保護的部分下,因此從外部無人能夠創建它的實例,只有派生類。
我的問題是,我的解決方案(在所有方面你可以想到)有什麼區別?
謝謝。
一個受保護的構造是明智的,但並不能阻止類被實例化:
class Foo
{
protected:
Foo() = default;
public:
static Foo make() { return Foo(); }
};
int main()
{
auto f = Foo::make();
}
在另一方面,抽象類不能被實例化,這是你可能想要的這裏。
但是,重要的問題是您是否確實需要多態性層次結構,您需要在運行時決定類型並通過基本指針處理異構對象集合。如果是這樣,那麼抽象的基礎就是它的走向。如果沒有,你就不能擁有一個沒有虛函數的抽象類,而受保護的構造函數(和析構函數)是唯一的方法來表明你想要一個不合理的基礎。
純虛函數將虛函數表的開銷添加到您的基類中,如果您需要保持對象非常小,這可能是一個問題。這種開銷可以通過使用受保護的構造函數和/或受保護的析構函數來避免。受保護的析構函數有助於防止通過基類指針進行命令刪除,而在沒有虛擬析構函數的情況下,該指針會導致未定義的行爲。
我認爲一個'protected'構造函數足以阻止這個類被實例化。你通過添加一個靜態成員函數來返回一個實例來「輕微地」作弊。即使是作弊,一個'protected'或'private'拷貝構造函數也會阻止你。 –
@NikBougalis:我還可以有一個靜態函數返回一個'新Foo' - 不需要複製:-S –
沒錯 - 但問題是如果你要作弊,那麼遊戲就結束了。但是你確實強調了一個私有構造函數是不夠的,它與基類中的純虛函數有什麼不同,以防止實例化。 –