2009-06-29 100 views

回答

73

當一個類是(打算作爲)一個抽象類時,受保護的構造函數是完全正確的。在這種情況下,你不希望從類中實例化對象,而只是使用它來繼承。

還有其他用例,例如某些構造參數應限制爲派生類。

11

一個用途是使用構造工廠模式

6

甲受保護的構造意味着只有派生成員可以構造類(和衍生的實例)的實例。這聽起來有點雞與雞蛋,但在實施班級工廠時有時很有用。

+3

從技術上講,這隻適用於所有ctors都受到保護的情況。 – MSalters 2009-06-29 09:09:42

+1

朋友類也可以調用受保護的構造函數(不僅僅是派生類)。 – 2013-09-29 03:48:32

+0

...並且調用受保護的構造函數的朋友類的使用將是對象具有常量(由構造函數設置)的成員的情況,但需要公開,但絕不會被其他公共訪問設置,從而保證該對象不會在其他地方創建,因此數據也不會在其他地方被修改。 – osirisgothra 2014-03-02 17:37:53

3

讓子類使用不應該直接訪問實例化器的構造函數。

3

你可以用它來限制可以創建它的類,例如:

class Level 
{ 
private: 

Level(); 
¨Level(); 

friend class LevelManager; 
}; 

,它可以創建它的一個實例中唯一的類是LevelManager類,所以你將永遠知道水平實例在LevelManager中創建。

7

非公開構造函數在有構造函數無法保證的構造要求時非常有用。例如,如果需要在構造函數之後立即調用初始化方法,或者如果對象需要向某個容器/管理器對象註冊自己,則必須在構造函數之外完成此操作。通過限制對構造函數的訪問並僅提供工廠方法,您可以確保用戶收到的任何實例都將履行其所有保證。這也通常用於實現一個單例,這實際上是類的另一個保證(只有一個實例)。

使構造函數受到保護(而不是私有)的原因與使其他方法或字段受保護而不是私有相同:因此它可以由子項繼承。也許你想在基類中使用公共的非虛擬工廠方法,它返回對派生類實例的引用;派生類顯然需要訪問父構造函數,但您仍然不想在工廠外創建它們。

2

對於具有副作用的工廠方法。

class mine { 

    private: 
    mine() {}; 

    protected: 
    mine(int id) : m_id(id) {}; 

    int m_id; 
    static int m_count; 

    public: 
    static mine* CreateOneOfMe() { 
     return mine(m_count++); 
    } 

    int GetId() { return m_id; } 

}; 

這創建了類的實例並確保它們中的每一個都具有唯一的遞增整數id。請注意,如果您要使用的構造函數不是默認構造函數,則您也必須隱藏默認構造函數。

5

受保護的構造函數可用於在沒有任何方法是純虛擬時有效地抽象類。

它在C++中並不是很抽象,因爲朋友類仍然可以使用它而不會覆蓋,但是接下來你將不得不聲明這些。

相關問題