C++ で小さな、限定されたスコープのクロスプラットフォーム UI ライブラリを作成しました。次のクラスを使用して UI コールバックを処理します。
// Base class for templated __Callback class to allow for passing __Callback
// objects as parameters, storing in containers, etc. (as Callback*)
class Callback
{
public:
virtual void execute() = 0;
virtual ~Callback() { }
protected:
Callback() { }
};
コメントで説明されているように、これはコールバックの基本クラスです。これにより、コールバックを引数として渡し、適切なコールバックを実行できるように UI ウィジェット内に格納できます (たとえば、ユーザーがボタンをクリックしたとき)。
// C++ has no callbacks (in the sense of an action [method] of a
// target [object]), so we had to roll our own. This class can be used
// directly, but the NEW_CALLBACK macro is easier.
template <class __TargetType>
class __Callback : public Callback
{
public:
typedef __TargetType TargetType;
typedef void (TargetType::*ActionType)(void);
virtual void execute()
{
(this->__target->*this->__action)();
}
__Callback(TargetType* target_, ActionType action_) :
Callback(), __target(target_), __action(action_) { }
virtual ~__Callback() { }
private:
// target object for the callback
TargetType* __target;
// action (method) of the target that will be called
ActionType __action;
};
このテンプレート化されたクラスは、コールバック パラダイムの要です。オブジェクトへのポインターとメンバー関数へのポインターを格納し、後でターゲット オブジェクトでメンバー関数を呼び出すことができるようにします。
#define NEW_CALLBACK(class_, obj_, act_) \
new __Callback<class_>(obj_, &class_::act_)
このマクロは、テンプレート化されたオブジェクトの作成を少し簡単にし__Callback
ます。
これは長い間うまく機能しています!コールバックを持つボタンは、次のようにインスタンス化できます。
MyClass* obj = new MyClass();
Button* btn = new Button("Title", NEW_CALLBACK(MyClass, obj, btnClicked));
これにより、後でウィンドウまたは他のコンテナーに配置されるボタンが作成され、クリックすると が呼び出されますobj->btnClicked()
。
さて、私の質問です(長いセットアップで申し訳ありません。これ以上削減できるとは思いません)。Callback*
オブジェクトをコピーする必要があるケースが発生しました。もちろん、基本クラスへのポインタなので、テンプレート化された派生クラスの型を特定することはできません。
Callback
コピーが元のオブジェクトと同じターゲットとアクションを指している状態で、任意のオブジェクトをコピーするにはどうすればよいでしょうか? または、このコールバックの問題に対して、私が取るべきまったく異なるアプローチがありますか (あまり変更したくないのですが)?
皆さんありがとう!