< C++ .NET Delegates & Events 1 | Main | C++ .NET Delegates & Events 3 >


 

 

Delegates and Events 2

generate, fire and handle the events...

 

 

 

  1. Calling Non-Static Member Functions Using Delegates

  2. Using Multicast Delegates

 

Calling Non-Static Member Functions Using Delegates

 

You can also call non-static member functions of classes by using delegates. By definition, a non-static member function has to be called on an object, so you need to tell the delegate the function it’s going to call and the object it’s going to use. You do so in the delegate’s constructor, like this:

// Declare a delegate bound to a non-static member

MyDelegate^ pDel = gcnew MyDelegate(pMyObject);

The constructor specifies the address of an object, pMyObject, and a member function belonging to the class to which pMyObject belongs. Calling Invoke on this delegate is equivalent to directly calling pMyObject->myFunction.

 

Using Multicast Delegates

 

We’ve seen how it’s possible to use a delegate to call a single function, but it’s also possible for a delegate to call more than one function with a single call to Invoke. A delegate that does so is called a multicast delegate and is derived from the System::MulticastDelegate class. All delegates that you create in managed C++ using the delegate keyword are multicast delegates. All delegate objects have an invocation list that holds the functions to be called. The invocation list for a normal delegate has one member. You manipulate the invocation lists for multicast delegates using the Combine and Remove methods.

If you look at the documentation for the Combine method, you’ll see that it takes two or more Delegate objects as its arguments. You don’t build up a multicast delegate by specifying more functions to add to its invocation list. Instead, a multicast delegate is built up by combining other delegates, which can, in turn, be single or multicast delegates themselves. The following exercise shows you how to create and use a multicast delegate.

 

1.        Open Visual C++/Studio .NET if it isn’t already opened and create a new CLR Console Application project named Multicast.

 

Creating a new CLR Console Application project named Multicast

 

2.        Open the Multicast.cpp source file and add the definition of a delegate to the top of the file, immediately after the using namespace System; line.

 

delegate void NotifyDelegate(int);

 

Adding the definition of a delegate

 

This delegate, named NotifyDelegate, can be bound to any function that takes one int as an argument and returns void.

 

3.        You’re going to call two functions through the multicast delegate. Because all functions called by delegates have to be members of a managed class, define two classes at the start of your project, each of which contains a static member function. Add the following code.

ref class Client1

{

   public:

       static void NotifyFunction1(int n)

       {

            Console::WriteLine(L"Client1: got value {0}", (Object^)(n));

       }

};

 

ref class Client2

{

   public:

       static void NotifyFunction2(int n)

       {

            Console::WriteLine(L"Client2: got value {0}", (Object^)(n));

       }

};

Adding codes to call two functions through the multicast delegate

 

These two classes are almost identical, both defining a single static member function that has the signature required by the delegate.

4.        You want to call the two static member functions through one delegate, but you can’t create a delegate to bind to two functions directly. Instead, you need to create two normal delegates (as you did in the previous exercise) and combine them into a multicast delegate. So, define two delegates in the main function, each of which binds to one of the static methods.

Console::WriteLine(L"Multicast Delegates");

// Declare two delegate

NotifyDelegate ^pDel1, ^pDel2;

 

// Bind them to the functions

pDel1 = gcnew NotifyDelegate(&Client1::NotifyFunction1);

pDel2 = gcnew NotifyDelegate(&Client2::NotifyFunction2);

 

Create two normal delegates and combine them into a multicast delegate

 

5.        At this stage, you could use Invoke to use both of the delegates, just as you did in the previous exercise. Build a multicast delegate from pDel1 and pDel2 by using the Delegate class’s static Combine method, like this:

// Combine the invocation lists of the two delegates

NotifyDelegate ^pDel3 =

dynamic_cast<NotifyDelegate^>(Delegate::Combine(pDel1, pDel2));

 

Adding codes to use the Delegate class’s static Combine method

 

Combine is a static member of the Delegate class that takes pointers to two delegates and returns you a new delegate whose invocation list combines the entries from both delegates. You need to use a cast because the pointer returned from Combine is simply a Delegate^ and it needs to be cast into a NotifyDelegate^ before it can be used. In other .NET languages, such as Microsoft Visual Basic and Visual C#, the syntax is simpler, but multicast delegates are still being created using the same mechanism.

 

6.        The multicast delegate is now used in exactly the same way as the normal delegates, using the Invoke method:

// Invoke the multicast delegate

Console::WriteLine(L"Invoking pDel3");

pDel3->Invoke(3);

Using delegates through the Invoke method

 

 

7.        When you build and run the program, you should see two lines of output, as shown in the following figure.

 

Delegate program output sample

 

Note that the functions are called in the order in which the delegates are combined, so if you want to change the order, you’ll need to change the way you create the multicast.

 

8.        You can use this multicast delegate as the basis for making up another one. Add the following code.

// Create a second multicast delegate and invoke it

NotifyDelegate ^pDel4 = dynamic_cast<NotifyDelegate^>(Delegate::Combine(pDel3, pDel3));

Console::WriteLine(L"Invoking pDel4");

pDel4->Invoke(3);

 

Adding codes for creating a second multicast delegate and invoke it

 

9.        Rebuild and re-run your program. In this case, you’re combining the invocation list of pDel3 twice, which means that you’ll get the output shown in the following figure when you invoke it.

 

Multicast delegate program output sample

 

10.     As the final part of this exercise, you can use the Remove method to remove an item from a multicast delegate’s invocation list. Here’s how:

 

// Remove an item

NotifyDelegate ^pDel5 = dynamic_cast<NotifyDelegate^>(Delegate::Remove(pDel3, pDel1));

Console::WriteLine(L"Invoking pDel5");

pDel5->Invoke(3);

 

Adding codes to use the Remove method to remove an item from a multicast delegate

 

11.     The Remove function takes two arguments: the delegate to be operated on, and the item to remove. If the item to be removed exists in the invocation list of the first delegate, it’s removed. In this example, pDel1 is being removed from the invocation list of pDel3, leaving only pDel2. If you invoke this delegate, you’ll see in the following figure that you get only the output from pDel2.

 

Delegate and remove() method program output sample

 

 

 

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

 


 

< C++ .NET Delegates & Events 1 | Main | C++ .NET Delegates & Events 3 >