ブーストバインド関数と同じことを行うために、独自のクラスを作成できます。クラスがしなければならないのは、関数型と関数を含むオブジェクトへのポインタを受け入れることだけです。たとえば、これはvoidreturnおよびvoidparamデリゲートです。
template<typename owner>
class VoidDelegate : public IDelegate
{
public:
VoidDelegate(void (owner::*aFunc)(void), owner* aOwner)
{
mFunction = aFunc;
mOwner = aOwner;
}
~VoidDelegate(void)
{}
void Invoke(void)
{
if(mFunction != 0)
{
(mOwner->*mFunction)();
}
}
private:
void (owner::*mFunction)(void);
owner* mOwner;
};
使用法:
class C
{
void CallMe(void)
{
std::cout << "called";
}
};
int main(int aArgc, char** aArgv)
{
C c;
VoidDelegate<C> delegate(&C::CallMe, &c);
delegate.Invoke();
}
さて、VoidDelegate<C>
は型なので、これらのコレクションを持つことは実用的ではないかもしれません。なぜなら、リストにクラスBの関数も含まれているとしたらどうでしょうか。できませんでした。
ここでポリモーフィズムが作用します。以下を呼び出す機能を持つインタフェースIDelegateを登録することができます。
class IDelegate
{
virtual ~IDelegate(void) { }
virtual void Invoke(void) = 0;
}
IDelegateを実装する場合VoidDelegate<T>
は、IDelegateのコレクションを使用できるため、さまざまなクラスタイプのメソッドへのコールバックを使用できます。