2011-01-10 9 views
48

可能性の重複:
What is the use of making constructor private in a class?プライベートコンストラクタ

たちがプライベートコンストラクタが必要なのでしょうか?プライベートコンストラクタを持つクラスをどのようにインスタンス化できますか?

+2

も参照してください。http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class – StuartLC

+0

よく質問し、この質問に対する回答も受け入れていますC++では無用ですが、C++で静的関数のクラスを作成するのは悪い味ですが、私たちは「純粋な」OOPの考え方に制約されません。 –

+0

http://stackoverflow.com/questions/2062560/what-is-the-use-of-making-constructor-private-in-a-class/16547184#16547184 –

答えて

64

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

名前付きコンストラクタイディオムは、クラスをより直感的に使用するためのものです。 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++(それらの間のシングルトンパターン)で使用されている理由の精神に合う他の応答がたくさんありました。

派生クラスはクラスのコンストラクタにアクセスできないため、別のことはprevent inheritance of your classです。もちろん、このような状況では、クラスのインスタンスを作成する関数が必要です。

+1

わかりませんが、コピーctorを持っていると良いでしょう。 RVOのためにそれについてtho、確信していない。 –

+3

@Pawel - クラスにプリミティブメンバー(2つの 'float')しかないので、C++のFAQの例では' Point'のコピーコンストラクタが定義されていないので、コンパイラのデフォルトコピーコンストラクタ(浅いコピー)で十分です。 – birryree

+1

+1最後に、シングルトンや工場ではない例です。名前付きコンストラクタははるかに便利です。 – chrisaycock

29

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

+17

+1。私は、特定のイディオムのケース使用法としてシングルトンを言及すると、常に下線を引いています。あなたにそれが起こらないようにしてください! :) –

2

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

5

インスタンスを生成できる他のメソッドがある場合は、コンストラクタをプライベートにするのが妥当です。明白な例はパターンシングルトン(すべての呼び出しは同じインスタンスを返します)と工場(すべての呼び出し、通常新しいインスタンスを作成する)です。

1

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

Singleton patternは、通常、誰も意図したタイプのインスタンスを作成しないようにします。

6

プライベートコンストラクタは、ユーザーがクラスをインスタンス化しないようにする場合に便利です。このようなクラスをインスタンス化するには、静的メソッドを宣言する必要があります。静的メソッドは 'new'を呼び出し、 ポインタを返します。

プライベートctorsを持つクラスは、コピーctorを必要とするため、STLコンテナに入れることはできません。

1

一般的な用途の1つは、次のようなテンプレートのtypedef回避策クラスのためである:

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

公共非実装コンストラクタがaswell動作しますが、プライベートコンストラクタは、リンク時のエラーではなくコンパイル時にエラーが発生しますもし誰かがMyLibrariesSmartPointer<SomeType>::typeの代わりにMyLibrariesSmartPointer<SomeType>を入れようとするなら、それは望ましいことです。

関連する問題