クラスAを考慮して、その作成を新規に限定したいと思います。あれは
A* a = new A; // Would be allowed.
A a; // Would not be allowed.
これはどのように達成できますか?
コンストラクターをプライベートにしてstatic
、動的に割り当てられたインスタンスを返すファクトリメソッドを提供できます。
class A
{
public:
static A* new_instance() { return new A(); }
private:
A() {}
};
生のポインターを返す代わりに、代わりにスマートポインターを返すことを検討してください。
class A
{
public:
static std::shared_ptr<A> new_instance()
{
return std::make_shared<A>();
}
private:
A() {}
};
1つのオプションは、コンストラクターをプライベートにし、静的ヘルパー関数を使用することです。
class A {
private:
A() {} // Default constructor
A(const A &a); // Copy constructor
public:
static A *create() { return new A; }
};
...
A a; // Won't compile
A *p = A::create(); // Fine
ただし、生のポインターではなく、スマートポインターを返すことを強く検討する必要があります。
はい、ファクトリパターンを使用してこれを行うことができます。
class A
{
A() {} //private by default
friend struct AFactory;
};
struct AFactory
{
static A* newA() { return new A; }
};
または同様のstatic
メンバー関数。
これは実際には非常に簡単です。デストラクタをプライベートにします。プライベートデストラクタを含むオブジェクトはスタック上に作成できないため、それらを作成する唯一の方法は、「new」を呼び出すことです。「deleteself」を呼び出す「delete()」メソッドなど、オブジェクトを削除するための別のメカニズムを提供する必要があります。
クライアントがクラスで何ができるかを制御しようとしていると思います。ここでの答えは、少し難解なテクニックを利用しています。システムを分離する一般的な方法は、インターフェースを使用することです。
あなたは要約を作ることができます:
class A
{
public:
virtual void doSomething() = 0;
virtual ~A() {}
};
そして、少なくとも1つの実装を行います。
class A_impl : public A
{
public:
virtual void doSomething()
{
// behaviour
}
};
A_impl
次に、他の回答が示唆するように、(スマート)ポインターを使用してのインスタンスをクライアントに返します。
あなたはただすることができません:
A* a;
?A
これは、オブジェクトへのポインタを宣言しているだけです。ただし、初期化されていないため、おそらく初期化する必要があります
A* a = NULL;
これは、型のオブジェクトへのポインターですがA
、既知の(非)値を指します。
編集:ここでの他の答えの複雑さを考えると、おそらく私は完全な質問を把握していません。
EDIT2:彼は、スタック上でのオブジェクトの作成を防ぎ、ヒープで作成されたオブジェクトとポインターを介したアクセスのみを許可できるかどうかを尋ねていますか?その場合、私の投票はファクトリパターンになります。