プライベートコンストラクターはどこに必要ですか? プライベートコンストラクターを持つクラスをインスタンス化するにはどうすればよいですか?
7 に答える
プライベート コンストラクターは、ユーザーがクラスを直接インスタンス化できないことを意味します。代わりに、Named Constructor Idiomstatic
のようなものを使用してオブジェクトを作成できます。この場合、クラスのインスタンスを作成して返すことができるクラス関数があります。
名前付きコンストラクタ イディオムは、クラスをより直感的に使用するためのものです。C++ FAQ で提供されている例は、複数の座標系を表すために使用できるクラス用です。
これは、リンクから直接取得されます。これは、異なる座標系の点を表すクラスですが、Rectangular 座標点と極座標点の両方を表すために使用できるため、ユーザーがより直感的に操作できるようにするために、返される座標系を表すためにさまざまな関数が使用され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つのことは、クラスの継承を防ぐことです。もちろん、この状況でも、クラスのインスタンスを作成する関数が必要です。
一般的な用途の 1 つは、クラスのインスタンスを 1 つだけ存在させたいシングルトン パターンです。その場合、static
オブジェクトのインスタンス化を行うメソッドを提供できます。このようにして、特定のクラスのインスタンス化されたオブジェクトの数を制御できます。
プライベート コンストラクターは、ユーザーがクラスをインスタンス化したくない場合に便利です。このようなクラスをインスタンス化するには、'new' を実行してポインターを返す静的メソッドを宣言する必要があります。
プライベート ctor を持つクラスは、コピー ctor が必要なため、STL コンテナーに配置できません。
インスタンスを生成できるメソッドが他にある場合は、コンストラクターを非公開にするのが合理的です。明らかな例は、Singleton (すべての呼び出しが同じインスタンスを返す) パターンと Factory (通常、すべての呼び出しが新しいインスタンスを作成する) です。
シングルトンを実装したい場合によくあります。クラスは、クラスがすでにインスタンス化されているかどうかをチェックし、インスタンス化されていない場合はコンストラクターを呼び出す静的な「ファクトリ メソッド」を持つことができます。
たとえば、フレンド クラスまたはフレンド関数内でプライベート コンストラクターを呼び出すことができます。
通常、シングルトン パターンでは、目的の型のインスタンスがこれ以上作成されないようにするために使用されます。
一般的な用途の 1 つは、次のような template-typedef ワークアラウンド クラスです。
template <class TObj>
class MyLibrariesSmartPointer
{
MyLibrariesSmartPointer();
public:
typedef smart_ptr<TObj> type;
};
明らかに、実装されていないパブリック コンストラクターも同様に機能しますが、プライベート コンストラクターは、誰かが のMyLibrariesSmartPointer<SomeType>
代わりにインスタンス化しようとすると、リンク時エラーではなくコンパイル時エラーを発生させMyLibrariesSmartPointer<SomeType>::type
ます。