web-dev-qa-db-ja.com

プライベートコンストラクタ

可能性のある複製:
クラスでコンストラクタをプライベートにすることの使用法は何ですか?

プライベートコンストラクターはどこで必要ですか?プライベートコンストラクターを持つクラスをインスタンス化するにはどうすればよいですか?

49
Atul

プライベートコンストラクターは、ユーザーがクラスを直接インスタンス化できないことを意味します。代わりに、クラスのインスタンスを作成して返すことができるstaticクラス関数がある Named Constructor Idiom のようなものを使用してオブジェクトを作成できます。

Named Constructor Idiomは、クラスをより直感的に使用するためのものです。 C++ FAQで提供されている例は、複数の座標系を表すために使用できるクラス用です。

これはリンクから直接取得されます。異なる座標系でポイントを表すクラスですが、長方形と極座標の両方を表すために使用できるため、ユーザーにとってより直感的にするために、返されるPointの座標系を表すために異なる関数が使用されます表します。

 #include <cmath>               // To get std::sin() and std::cos()

 class Point {
 public:
   static Point rectangular(float x, float y);      // Rectangular coord's
   static Point polar(float radius, float angle);   // Polar coordinates
   // These static methods are the so-called "named constructors"
   ...
 private:
   Point(float x, float y);     // Rectangular coordinates
   float x_, y_;
 };

 inline Point::Point(float x, float y)
   : x_(x), y_(y) { }

 inline Point Point::rectangular(float x, float y)
 { return Point(x, y); }

 inline Point Point::polar(float radius, float angle)
 { return Point(radius*std::cos(angle), radius*std::sin(angle)); }

プライベートコンストラクターがC++で使用される理由(その中のシングルトンパターン)にも適合する他の多くの応答がありました。

派生クラスはクラスのコンストラクターにアクセスできないため、これを使ってできるもう1つのことは クラスの継承を防ぐ です。もちろん、この状況では、クラスのインスタンスを作成する関数が必要です。

64
wkl

一般的な用途の1つは、クラスのインスタンスを1つだけ存在させるシングルトンパターンです。その場合、オブジェクトのインスタンス化を行うstaticメソッドを提供できます。これにより、特定のクラスでインスタンス化されるオブジェクトの数を制御できます。

29
Naveen

プライベートコンストラクターは、ユーザーがクラスをインスタンス化したくない場合に便利です。そのようなクラスをインスタンス化するには、静的メソッドを宣言する必要があります。このメソッドは「新規」を実行し、ポインターを返します。

プライベートアクターを持つクラスは、コピーアクターを必要とするため、STLコンテナーに配置できません。

6
vrdhn

インスタンスを生成できる他のメソッドがある場合、コンストラクタをプライベートにするのが妥当です。明らかな例は、Singleton(すべての呼び出しが同じインスタンスを返す)とFactory(すべての呼び出し通常 create new instance)のパターンです。

5
Andrey

シングルトンを実装する場合は一般的です。クラスは、クラスが既にインスタンス化されているかどうかをチェックし、インスタンス化されていない場合はコンストラクターを呼び出す静的な「ファクトリーメソッド」を持つことができます。

2
unwind

たとえば、friendクラスまたはfriend関数内でプライベートコンストラクターを呼び出すことができます。

シングルトンパターン は通常、これを使用して、意図したタイプのインスタンスがこれ以上作成されないようにします。

1
Simone

一般的な用途の1つは、次のようなtemplate-typedef回避策クラスです。

template <class TObj>
class MyLibrariesSmartPointer
{
  MyLibrariesSmartPointer();
  public:
    typedef smart_ptr<TObj> type;
};

明らかに、実装されていないパブリックコンストラクターも機能しますが、プライベートコンストラクターは、誰かがMyLibrariesSmartPointer<SomeType> の代わりに MyLibrariesSmartPointer<SomeType>::type、これは望ましいことです。

1
smerlin