ボタンクラス(抽象)を作成しようとしているので、プログラムのロード時に動的にクリックされたときにそのボタンがどの機能をトリガーするかを設定できます。
XML ファイルを読み取ってすべてのボタンを作成したいのですが、これはコードの複製を避けるためです。そのため、「汎用」ボタン クラスを 1 つだけ持つと非常に便利です。
メソッドの所有者へのポインターや問題の名前のメソッド、またはメソッドへの直接ポインターなど、メソッドに関する必要な情報を動的に渡すことができるかどうか疑問に思っていました。
ボタンクラス(抽象)を作成しようとしているので、プログラムのロード時に動的にクリックされたときにそのボタンがどの機能をトリガーするかを設定できます。
XML ファイルを読み取ってすべてのボタンを作成したいのですが、これはコードの複製を避けるためです。そのため、「汎用」ボタン クラスを 1 つだけ持つと非常に便利です。
メソッドの所有者へのポインターや問題の名前のメソッド、またはメソッドへの直接ポインターなど、メソッドに関する必要な情報を動的に渡すことができるかどうか疑問に思っていました。
SetFunctor
ジェネリックButton
クラスにメソッドを作成できます。このメソッドは、関数オブジェクトをパラメーターとして受け入れます。次にCall
、関数オブジェクト内にラップされた関数を呼び出すメソッドを作成します。このようなもの:
template<typename FUNC>
class Functor
{
typedef FUNC (*FC)();
FC func;
public:
Functor( FC f ) : func(f) {}
~Functor() {}
FUNC Call() { return func(); }
FUNC operator()() const { return Call(); }
};
class Button
{
std::auto_ptr<Functor<void> > pfunc;
public:
Button() {}
~Button() {}
void SetFunctor( void(*fc)() )
{
pfunc.reset( new Functor<void>( fc ) ); // now owns ptr;
}
void Call()
{
pfunc->Call();
}
};
...
void changeColor()
{
// do work
}
Button obj;
obj.SetFunctor( changeColor );
obj.Call();
もちろん、より優れたスマートポインターやより優れた手法を使用することもできますが、これにより、私が示唆していたことの要点がわかります。また、このFunctorオブジェクトは、パラメーターを持たない関数のみを受け入れることができることに注意してください。これはお好みに合わせて変更できます。お役に立てば幸いです。
更新:いくつかの修正が追加されました。申し訳ありません!
関数へのポインターはランタイム アーティファクトであるため、それをオフライン構成に格納することはできません。あなたの説明に合うかもしれない2つの解決策があります:
経験から言えば、そのような施設を構築することは通常やり過ぎであり、構成はすぐにアプリ自体よりも重くなります。
いくつかの追加のポインター: Boost.Signals、QT Signals、コマンドおよび責任の連鎖の設計パターン。
ボタンをC++の関数にリンクするには、いくつかの方法があります。関数ポインター(やや怖い)、または関数ポインターの機能に型の安全性を提供するシグナルとスロットのパターンを使用できます。
構成ファイルに基づいて実行時に関数ポインターまたはシグナルとスロットを配線する限り、これをエレガントに行うにはリフレクションが必要になりますが、C++では提供されません。これは醜い部分になると思います。