2009-06-29 13 views

答えて

73

クラスが抽象クラスである場合、保護されたコンストラクタはまさに正しいクラスです。そのような状況では、クラスからオブジェクトをインスタンス化するのではなく、それを継承するためにオブジェクトを使用するだけです。

ある種の構築パラメータを派生クラスに限定する必要がある場合など、他の使用例があります。

+7

+1しかし、必ずしも抽象クラスである必要はありません。しかし、それはしばしばケースです。 – ralphtheninja

+4

基本クラスを定義するために関数を純粋仮想として宣言するだけでは不十分ですか?または、上記は純粋な仮想関数がない場合です。そのような抽象クラスの派生クラスの作成イベントとは何ですか? –

+0

@Henk Holterman C++標準のセクション10.4「抽象ク​​ラス」を参照してください。 –

11

1つの用途は、そのコンストラクタを使用して保護されたコンストラクタのみ派生メンバーは、クラス(および派生インスタンス)のインスタンスを構築することができることを意味する工場パターン

6

とすることができます。これはちょっとした鶏と卵が聞こえますが、クラスファクトリを実装するときに便利なことがあります。

+3

技術的には、これはすべてのctorが保護されている場合にのみ適用されます。 – MSalters

+1

フレンドクラスは保護されたコンストラクタ(派生クラスだけでなく)を呼び出すこともできます。 –

+0

...保護されたコンストラクタを呼び出すフレンドクラスの使用は、定数(コンストラクタによって設定される)を持ち、パブリックである必要があるが他のパブリックアクセスによって決して設定されないメンバを持つオブジェクトの場合には、オブジェクトはどこか他の場所に作成されることはありません。そのため、データは他の場所でも変更されません。 – osirisgothra

3

サブクラスがインスタンシエーターが直接アクセスできないコンストラクターを使用できるようにする。

3

次の例のように、それを作成することができ、クラスを制限するためにそれを使用することができます。それのインスタンスを作成することができます

class Level 
{ 
private: 

Level(); 
¨Level(); 

friend class LevelManager; 
}; 

唯一のクラスはLevelManagerクラスですので、あなたは常にレベルということを知っているだろうインスタンスがLevelManagerで作成されます。

+0

trueの間、それは保護されていないプライベートコンストラクタです。 – David

+0

ahaha申し訳ありませんが、私は間違っています。私の投稿を削除しますか? –

7

非公開コンストラクタは、コンストラクタによってのみ保証されることができない構築要件がある場合に便利です。たとえば、コンストラクタの直後に初期化メソッドを呼び出す必要がある場合や、オブジェクトがコンテナ/マネージャオブジェクトに登録する必要がある場合は、コンストラクタの外側で初期化メソッドを実行する必要があります。コンストラクタへのアクセスを制限し、ファクトリメソッドのみを提供することで、ユーザが受け取るインスタンスがすべて保証されることを保証することができます。これは一般に、シングルトンを実装するためにも使用されます。シングルトンは、実際にはクラスが保証する単なるインスタンスです(単一のインスタンスのみが存在する)。

コンストラクタをプライベートではなく保護する理由は、プライベートではなく他のメソッドまたはフィールドをprotectedにする理由と同じです。つまり、子によって継承されるようになります。おそらく、派生クラスのインスタンスへの参照を返す、基本クラスにpublicで非仮想のファクトリメソッドが必要な場合があります。派生クラスは明らかに親コンストラクタへのアクセスを必要としますが、それでもあなたのファクトリの外にそれらを作成したくないのです。

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++の意味では抽象的ではありませんが、宣言する必要があります。

関連する問題