なぜ誰かがコンストラクターを保護すると宣言するのでしょうか?コンストラクターは、スタックでの作成を許可しない目的でプライベートとして宣言されていることを私は知っています。
9 に答える
クラスが (として意図された) 抽象クラスである場合、保護されたコンストラクターはまさに正しいです。そのような状況では、オブジェクトをクラスからインスタンス化するのではなく、継承するためにのみ使用します。
特定の構築パラメーターのセットを派生クラスに制限する必要がある場合など、他の使用例があります。
非公開コンストラクターは、コンストラクターだけでは保証できない構築要件がある場合に役立ちます。たとえば、初期化メソッドをコンストラクターの直後に呼び出す必要がある場合、またはオブジェクトがそれ自体をコンテナー/マネージャーオブジェクトに登録する必要がある場合、これはコンストラクターの外部で実行する必要があります。コンストラクターへのアクセスを制限し、ファクトリメソッドのみを提供することで、ユーザーが受け取るすべてのインスタンスがすべての保証を確実に満たすようにすることができます。これは、シングルトンを実装するためにも一般的に使用されます。これは、クラスが行うもう1つの保証です(インスタンスは1つだけです)。
コンストラクターをプライベートではなく保護する理由は、他のメソッドまたはフィールドをプライベートではなく保護する理由と同じです。これにより、コンストラクターを子に継承できるようになります。おそらく、派生クラスのインスタンスへの参照を返す、基本クラスのパブリックな非仮想ファクトリメソッドが必要です。派生クラスは明らかに親コンストラクターへのアクセスを望んでいますが、それでもファクトリの外部でそれらを作成したくはありません。
保護されたコンストラクターを使用して、クラスのメソッドが純粋仮想でない場合に、クラスを効果的に抽象化できます。
フレンド クラスはオーバーライドせずに使用できるため、C++ の意味では抽象的ではありませんが、これらを宣言する必要があります。
1つの用途はファクトリパターンである可能性があります
保護されたコンストラクターとは、派生メンバーのみがそのコンストラクターを使用してクラスのインスタンス(および派生インスタンス)を構築できることを意味します。これは少し鶏が先か卵が先かと思われますが、クラスファクトリを実装するときに役立つ場合があります。
副作用のあるファクトリーメソッド用。
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 を持つことが保証されます。使用するコンストラクターがデフォルトでない場合は、デフォルトも非表示にする必要があることに注意してください。
インスタンシエーターが直接アクセスできないコンストラクターをサブクラスで使用できるようにするため。
これを使用して、それを作成できるクラスを制限できます。次に例を示します。
class Level
{
private:
Level();
~Level();
friend class LevelManager;
};
そのインスタンスを作成できる唯一のクラスは LevelManager クラスであるため、Level インスタンスが LevelManager で作成されることが常にわかります。