頭のてっぺんから推測します...いいえ、存在しません(少なくとも、C ++の場合はそうではありません)。
あなたの提案は複雑な状況を暗示しています(コールバックを使用していなかったとしても)。あなたは、それ自体が破壊されると、それを参照するデータ構造から(潜在的に)それ自体の参照を削除する処理を行う何かを求めています。これはかなり難しい注文であり、特にSTLが意図したことではありません。
あなたが本当にこれをしたいのなら(そして私はあなたがそうすると確信しています)、それからここに私の最初の考えがあります。オブジェクトがデータ構造に追加されるたびに、たとえば。のようなメソッドを使用して、データ構造がオブジェクトに登録されていることを要求できますObject::Register(const std::vector<Object> &v)
。次に、への参照(実際には、おそらくポインタをキャプチャします)を保存できるので、破棄時にオブジェクトを削除するvector
ように指示できます。vector
もちろん、これには2つの問題があります。
- それはまだ非常に複雑です(特に、単なるベクトルよりも多くの構造をサポートしたい場合、そして完全に一般的なソリューションを探している場合はさらにそうです)。
- オブジェクトが構造に追加されるすべての場所で、他のコーダーがこのスタイルに従う必要があります
- おそらく、のデストラクタを編集する必要が
Object
ありますが、これは行うべきではないと明示的に指示しました。
だから、ええ、そこではあまり助けにはなりません。
個人的には、イベント(具体的には、c#で使用するようなデリゲートベースのイベント)を中心に展開する、はるかに好ましいソリューションがあります。これらがどのように機能するかをよく知らない場合は、このプログラミングガイドをお読みください。繰り返しになりますが、c#ではなくc ++を使用しているため、また、ほとんど自分で説明するため、そうではないかもしれません。
イベントのアイデアが気に入った理由の1つは、すでにコールバックを使用していることです。デリゲート(c#デリゲートのように)は、コールバックの単なる拡張です。vector<Callback>
これらは基本的に、動作をDelegate
クラスにカプセル化します。このDelegate
クラスでは、関数呼び出し演算子をオーバーロードすると、これらすべてのメソッドを1回の操作で呼び出すことができます。また、delegate
すでに使用しているように、パラメータ化されたタイプである可能性があります。(実際、C++0x
すぐに使えるようになると、可変個引数テンプレートも非常に役立ちます)。
Delegate
とにかく、このすべてのポイントは、任意のクラスのメンバー変数などを持つことができるということです。
class Object
{
public:
... // whatever constructors, etc. you might need
Delegate<void, Collection, EventArgs> destroyHandler;
... // and number of event handlers can be used.
};
これで、どのデータ構造クラスでも、次のような方法でコールバックを登録できます。
obj.destroyHandler += myDelegate;
ここmyDelegate
で、必要なタイプの関数はどこにありますか。
ただし、このアプローチにはさらに多くの問題があります。具体的には、イベントモデルを認識するデータ構造で満たされたまったく新しいライブラリが必要です。既存のSTLコンテナは単純にラップできるため、これはそれほど難しいことではありません。それは大変な作業であり、誰もがあなたの新しいライブラリを使用することを決定しなければならないでしょう。
別の落とし穴が行にありDelegate<void, Collection, EventArgs> destroyHandler;
ます。これらのタイプパラメータのそれぞれはどういう意味ですか?まあ、void
かなり明確にする必要があります:それはメソッドの単なるreturnタイプです。また、EventArgs
単純です。コールバックに渡す必要のあるデータをラップするだけです。タイプは最もCollection
奇妙です-使用されるタイプコレクションをパラメータ化するのはなぜですか?
これは、C++でメンバー関数へのポインターを使用する際の厄介な問題を回避するためです。このようなポインターは可能ですが、使用するのはひどいものであり、(私が知る限り)複数の型からメンバー関数へのポインターを取得して単一のコレクションに格納する方法はありません。
代わりに、私が過去に試したことは(私は実際にはアイデアを完成させていませんでしたが)次のようなものでした
class MyVector
{
static void DestructionHandler( MyVector & v, EventArgs & args )
{
// ... Handler code goes here
}
};
注意すべきことはパラメータMyVector & v
です:それは通常のthis
ポインタを置き換えます。また、メソッドは次のとおりであることに注意してください。static
これにより、通常の古いCスタイルの関数ポインターとして使用できるようになります。
とにかく、私は少し夢中になっているかもしれませんが、これらすべてをまとめると、他のOOP言語で非常に人気のあるかなりまともなイベントベースのシステムを手に入れることができます。それに、大変な注文だったと言いました!