C++(Visual Studio 2010)で共有ポインタを使用し始め、次の問題が発生しています。クラスがスタックまたはデータメンバとしてインスタンス化されないようにする
私は、モジュールに特定の条件での動作方法を伝えるインターフェイスを定義する新しいモジュールを作成しています。これは、(ちょうど私の問題を説明するための人工例)このようなものです:
// Interface that should be implemented by user of the module
class RingAlert
{
public:
virtual void ring() = 0;
};
// Module that does something important
class Module
{
public:
Module (RingAlert &ringAlert) : m_ringAlert(ringAlert) {}
void dosomething(); // may call RingAlert::ring if something goes wrong.
private:
RingAlert &m_ringAlert;
};
はモジュールのユーザーのために、それを容易にする、とRingAlertは他のモジュールに渡される可能性があるため、私は今、これを作っていますこのような共有ポインタは、:
typedef std::shared_ptr<RingAlert> RingAlertPtr;
class Module
{
public:
Module (RingAlertPtr ringAlert) : m_ringAlert(ringAlert) {}
void dosomething(); // may call RingAlert::ring if something goes wrong.
private:
RingAlertPtr m_ringAlert;
};
今モジュールのユーザーは、新しいRingAlertインスタンスを作成することができ、単にどこかでそれを維持し、アプリケーションの終了時に、それを削除せずに、モジュールに渡します。この例では
class MyRingAlert : public RingAlert
{
public:
virtual void ring() {std::cout << "ring ring" << std::endl;}
};
class Application
{
public:
private:
MyRingAlert m_myRingAlert;
};
// later, somewhere in application code
Module m(RingAlertPtr(&m_myRingAlert));
アプリケーションは、データメンバのアドレスを取得し、共有ポインタにそれを置く、アプリケーションがこのような何かをしなければ
問題が開始されます。 アプリケーションの後で、モジュールのデストラクタは共有ポインタを削除し、参照カウントを減らします。を削除します。これはアプリケーションのデータメンバーであるため、削除しないでくださいクラス。
私は(ラムダのを使用しても機能を使用して、わずかにクリーナーソリューションを持っている)、これを実行してインスタンスを削除するから共有ポインタを防止する方法を見つけた:
Module m(RingAlertPtr(&m_myRingAlert,[](void *){});
これは私の問題を解決するが、私は」なぜなら、ApplicationクラスがModuleクラスの前で破壊されたとしても問題は残るからです。
唯一の良い解決策は、力に新しい RingAlertのインスタンス(または実際にRingAlertを実装するクラス)へのアプリケーションの残りの部分のようです。
これはできますか? スタック上の基本クラスのサブクラスまたはdatamemberとしてコードをインスタンス化できないようにする方法はありますか? 言い換えれば、インスタンス化したい場合、ベースクラスのサブクラスを強制的に新しくすることができますか?
[私に派生したクラスのオブジェクトを "new"のみで作成する方法をユーザーに強制する方法](http://stackoverflow.com/questions/2833752/how-to-enforce-users-to-create -objects-of-class-derived-from-new-only) – sharptooth