Delegates and Events
An event is a member of a class that enables an object to signal when a particular event has occurred, and the signaling process for an event involves a delegate that provides the mechanism for responding to the event is some way. A mouse click is a typical example of an event and the object that originated the mouse click event would signal that the event has occurred by calling one or more functions that are responsible for dealing with the event; a delegate would provide the means to access the function that is to respond to the event. Let's look at delegates first and return to events a little later in this chapter.
The idea of a delegate is very simple - it's an object that can encapsulate one or more pointers to functions that have a given parameter list and return type. A function that a delegate points to will deal with a particular kind of event. Thus a delegate provides a similar facility in C++/CLI to a function pointer in native C++. Although the idea of a delegate is simple, however, the detail of creating and using delegates can get a little confusing so it's time to concentrate.
Declaring Delegates
The declaration for a delegate looks like a function prototype preceded by the delegatekeyword but in reality it defines two things: the reference type name for a delegate object, and the parameter list and return type of the functions that can be associated with the delegate. A delegate reference type has the System::Delegateclass as a base class so a delegate type always inherits the member of this class. The declaration for a delegate looks like a function prototype preceded by the delegatekeyword but in reality it defines a reference type for the delegate, and the signature of the functions that can be associated with the delegate. Here's an example of a declaration for a delegate:
public delegate void Handler(int value); // Delegate declaration
This defines a delegate reference type Handler where the Handler type is derived from System::Delegate. An object of type Handler can contain pointers to one or more functions that have a single parameter of type int and a return type that is void. The functions pointed to by a delegate can be instance functions or static functions.
Creating Delegates
Having defined the delegate type, you can now create delegate objects of this type. You have a choice of two constructors for a delegate: one that accepts a single argument and another that accepts two arguments.
The argument to the delegate constructor that accepts one argument must be a static function member of a class or a global function that has the return type and parameter list specified in the delegate declaration. Suppose you define a class with the name HandlerClasslike this:
public ref class HandlerClass { public:
static void Fun1(int m)
{ Console::WriteLine(L"Function1 called with value {0}", m); } Chapter 9: Class Inheritance and Virtual Functions
static void Fun2(int m) { Console::WriteLine(L"Function2 called with value {0}", m); } void Fun3(int m)
{ Console::WriteLine(L"Function3 called with value {0}", m+value); } void Fun4(int m)
{ Console::WriteLine(L"Function3 called with value {0}", m+value); } HandlerClass():value(1){} HandlerClass(int m):value(m){} protected: int value; };
The class has four functions with a parameter of type intand a return type of void. Two of these are static functions and two are instance functions. It also has two constructors including a no-arg constructor. This class doesn't do much except produce output where you'll be able to determine which function was called and for instance functions what the object was.
