< C++ .NET Delegates & Events 4 | Main | C++ .NET Delegates & Events 6 >


 

 

Delegates and Events 5

generate, fire and handle the events

 

 

  1. The Unbound Delegates

 

 

The Unbound Delegates

 

An unbound delegate allows you to pass an instance of the type whose function you want to call when the delegate is called. Unbound delegates are especially useful if you want to iterate through the objects in a collection (using for each, in) keywords, and call a member function on each instance. The following is a summary of how to declare, instantiate, and call bound and unbound delegates:

 

Action

Bound Delegates

Unbound Delegates

Declare

The delegate signature must match the signature of the function you want to call through the delegate.

The first parameter of the delegate signature is the type of this for the object you want to call. After the first parameter, the delegate signature must match the signature of the function you want to call through the delegate.

Instantiate

When you instantiate a bound delegate, you can specify an instance function or a global or static member function. To specify an instance function, the first parameter is an instance of the type whose member function you want to call and the second parameter is the address of the function you want to call. If you want to call a global or static member function, you only pass the name of the static member function or the name of a global function.

When instantiating an unbound delegate, you only pass the address of the function you want to call.

Call

When you call a bound delegate, you only pass the parameters required by the delegate signature.

Same as a bound delegate (but remember the first parameter must be an instance of the object containing the function you want to call).

 

Table 3

 

The following code sample demonstrates the syntax for declaring, instantiating, and calling unbound delegates.

 

 

 

 

 

 

 

// unbound delegates

// compile with: /clr

 

#include "stdafx.h"

 

using namespace System;

 

ref struct DeleStrucRef

{

   DeleStrucRef(){}

   DeleStrucRef(int i) : m_i(i) {}

   void Print(int i) { System::Console::WriteLine("Ref, m_i + i = {0}", m_i + i);}

 

   private:

      int m_i;

};

 

value struct DeleStrucVal

{

   void Print() { System::Console::WriteLine("Value, m_i = {0}", m_i);}

   int m_i;

};

 

delegate void Delegate1(DeleStrucRef^, int i);

delegate void Delegate2(DeleStrucRef%, int i);

 

delegate void Delegate3(interior_ptr<DeleStrucVal>);

delegate void Delegate4(DeleStrucVal%);

 

delegate void Delegate5(int i);

delegate void Delegate6();

 

int main(array<System::String ^> ^args)

{

      DeleStrucRef^ newobj1 = gcnew DeleStrucRef(1);

      DeleStrucRef% newobj2 = *gcnew DeleStrucRef(2);

 

      Delegate1 ^ Unbound_Delegate1 = gcnew Delegate1(&DeleStrucRef::Print);

      // delegate takes a handle

      Unbound_Delegate1(newobj1, 1);

      Unbound_Delegate1(%newobj2, 1);

 

      Delegate2 ^ Unbound_Delegate2 = gcnew Delegate2(&DeleStrucRef::Print);

      // delegate takes a tracking reference (must deference the handle)

      Unbound_Delegate2(*newobj1, 1);

      Unbound_Delegate2(newobj2, 1);

      // instantiate a bound delegate to an instance member function

      Delegate5 ^ Bound_Del = gcnew Delegate5(newobj1, &DeleStrucRef::Print);

      Bound_Del(1);

 

      // instantiate value types

      DeleStrucVal val1 = {7};

      DeleStrucVal val2 = {8};

 

      Delegate3 ^ Unbound_Delegate3 = gcnew Delegate3(&DeleStrucVal::Print);

      Unbound_Delegate3(&val1);

      Unbound_Delegate3(&val2);

 

      Delegate4 ^ Unbound_Delegate4 = gcnew Delegate4(&DeleStrucVal::Print);

      Unbound_Delegate4(val1);

      Unbound_Delegate4(val2);

 

      Delegate6 ^ Bound_Delegate3 = gcnew Delegate6(val1, &DeleStrucVal::Print);

      Bound_Delegate3();

 

      return 0;

}

 

Output:

C++ .NET program output example - the unbound delegate

 

The following program sample shows how you can use unbound delegates and the for each, in keywords to iterate through objects in a collection and call a member function on each instance.

// unbound delegates

// compile with: /clr

 

#include "stdafx.h"

 

using namespace System;

 

ref class RefClass

{

   String^ MyStr;

   public:

         RefClass(String^ str) : MyStr(str) {}

         void Print() { Console::Write(MyStr); }

};

 

delegate void PrintDelegate(RefClass^);

 

int main()

{

      PrintDelegate^ newdel = gcnew PrintDelegate(&RefClass::Print);

      array< RefClass^ >^ newarrayobj = gcnew array<RefClass^>(10);

      for (int i = 0; i < newarrayobj->Length; ++i)

         newarrayobj[i] = gcnew RefClass(i.ToString());

      for each (RefClass^ RefCl in newarrayobj)

         newdel(RefCl);

      Console::WriteLine();

 

      return 0;

}

 

Output:

 

C++ .NET program output example - the unbound delegate

 

The following program sample creates an unbound delegate to a property's accessor functions.

// unbound delegates

// compile with: /clr

 

#include "stdafx.h"

 

using namespace System;

 

ref struct RefStruc

{

      property int P1

      {

            int get() { return m_i; }

            void set(int i) { m_i = i; }

      }

 

      private:

            int m_i;

};

 

delegate void DelBSet(RefStruc^, int);

delegate int DelBGet(RefStruc^);

 

int main()

{

      RefStruc^ newobj = gcnew RefStruc;

      DelBSet^ delBSet = gcnew DelBSet(&RefStruc::P1::set);

      delBSet(newobj, 100);

      DelBGet^ delBGet = gcnew DelBGet(&RefStruc::P1::get);

      Console::Write("Get...set value: ");

      System::Console::WriteLine(delBGet(newobj));

 

      return 0;

}

 

Output:

 

 

Program sample output that creates an unbound delegate to a property's accessor functions

 

The following code sample shows how to invoke a multicast delegate, where one instance is bound and one instance is unbound.

 

// unbound delegates

// compile with: /clr

 

#include "stdafx.h"

 

using namespace System;

 

ref class RefClas

{

      public:

         RefClas(int i) : m_i(i) {}

      void funct(RefClas ^ param)

      {

         System::Console::WriteLine("In funct(RefClas ^ param)");

      }

      void funct()

      {

         System::Console::WriteLine("In funct()");

      }

      private:

         int m_i;

};

 

delegate void Del(RefClas ^);

 

int main()

{

   RefClas ^newobje1 = gcnew RefClas(11);

   RefClas ^newobje2 = gcnew RefClas(12);

   Del^ delobj = gcnew Del(newobje1, &RefClas::funct);

   delobj += gcnew Del(&RefClas::funct);

   delobj(newobje2);

   return 0;

};

 

Output:

 

C++ .NEt code sample shows how to invoke a multicast delegate, where one instance is bound and one instance is unbound

 

The following program sample shows how to create and call an unbound generic delegate.

// unbound delegates

// compile with: /clr

 

#include "stdafx.h"

 

using namespace System;

 

ref struct RefStruc

{

      RefStruc(int i) : m_i(i) {}

      int funct(RefStruc ^) { return 999; }

      int funct() { return m_i + 5; }

      int m_i;

};

 

value struct ValStruc

{

      int funct(ValStruc%) { return 999; }

      int funct() { return m_i + 5; }

      int m_i;

};

 

generic <typename Typ>

delegate int Del(Typ mytyp);

generic <typename Typ>

delegate int DelV(Typ% mytyp);

 

int main(array<System::String ^> ^args)

{

      RefStruc^ newobj = gcnew RefStruc(7);

      System::Console::WriteLine("Ref: {0}", (gcnew Del<RefStruc^>(&RefStruc::funct))(newobj));

      ValStruc val;

      val.m_i = 9;

      System::Console::WriteLine("Value: {0}", (gcnew DelV<ValStruc >(&ValStruc::funct))(val) );

      return 0;

}

 

Output:

 

 

 

 

Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

 


 

< C++ .NET Delegates & Events 4 | Main | C++ .NET Delegates & Events 6 >