delegateはC++の関数ポインタ配列のような機能です。ここではまずC++の関数ポインタ配列の例を示します。
typedef void (*MYFUNC)(int); void func1(int i){ } void func2(int j){ } struct C { static void func3(int k){} }; void callall(MYFUNC f[]) { for ( int i=0 ; i < 3 ; ++i ) { (*f[i])(1); } } int main() { MYFUNC funcs[3]; funcs[0] = &func1; funcs[1] = &func2; funcs[2] = &C::func3; callall(funcs); return 0; }
上記の場合、MYFUNCにはクラスの非staticのメンバ関数や、operator()などが定義されているクラスのインスタンスを設定することはできません。
次に、上記の例をdelegateを使って書くと以下のようになります。
using namespace System; delegate void MyDele(int); void func1(int i){} void func2(int j){} ref struct C { static void func3(int k) {} }; ref struct D { void func4(int l) {} }; ref struct F { void operator()(int m) {} }; int main() { MyDele^ dele; dele = gcnew MyDele(&func1); dele += gcnew MyDele(&func2); dele += gcnew MyDele(&C::func3); D^ d = gcnew D; dele += gcnew MyDele(d, &D::func4); F^ f = gcnew F; dele += gcnew MyDele(f, &F::operator()); dele(1); return 0; }
この場合、delegateが戻り値がvoidですが、戻り値を持つ場合、最後に呼び出された関数の戻り値が帰ります。
==でdelegateの比較が行われる場合はハンドルの比較が行われるのではなく、delegateが持っている関数によって比較されます。また-=によってdelegateから削除される場合も関数の比較が行われます。
using namespace System; delegate void MyDele(int); void func1(int i) { Console::WriteLine("func1"); } void func2(int j) { Console::WriteLine("func2"); } int main() { MyDele^ dele; dele += gcnew MyDele(&func1); dele += gcnew MyDele(&func2); MyDele^ dele2 = gcnew MyDele(func1); dele2 += gcnew MyDele(&func2); if ( dele == dele2 ) // 真になる Console::WriteLine("TRUE"); else Console::WriteLine("FALSE"); dele -= gcnew MyDele(&func1); // 削除される dele(1); // func2のみ呼ばれる return 0; }