Printer Friendly Version      Send     
Click to Rate and Give Feedback
Related Articles

Our security experts present 10 vulnerable pieces of code. Your mission is to find the holes (a.k.a. bad security practices) in the code.

Michael Howard and Bryan Sullivan

MSDN Magazine November 2008

...

Read more!

With the release of Windows Vista, C++ developers will be happy to know there's plenty of magic left to perform. This new column will provide the necessary insight.

Kenny Kerr

MSDN Magazine August 2007

...

Read more!

Howard Dierking talks to the inventor of C++, Bjarne Stroustrup, about language zealots, the evolution of programming, and what’s in the future of programming.

Howard Dierking

MSDN Magazine April 2008

...

Read more!

The new Task Scheduler in Windows Vista can do so much more than previous versions. We introduce some basic concepts and building blocks you can put to use in your own scheduled task projects.

Kenny Kerr

MSDN Magazine October 2007

...

Read more!

In this month's installment, Kenny Kerr sings the praises of the new Visual C++ 2008 Feature Pack, which brings modern conveniences to Visual C++.

Kenny Kerr

MSDN Magazine June 2008

...

Read more!

Also by this Author

This month Paul DiLascia codes some Microsoft Office-style dialog box features.

Paul DiLascia

MSDN Magazine August 2006

...

Read more!

Paul DiLascia

MSDN Magazine February 2006

...

Read more!

Many of you are no doubt in the process of upgrading to Visual Studio® 2005, so I thought now would be a good time to relate some of my own experiences with the new compiler. What took me so long? Hey, I'm a retro kind of guy! Better late than never!.

Paul DiLascia

MSDN Magazine June 2006

...

Read more!

Paul DiLascia

MSDN Magazine April 2006

...

Read more!

Paul DiLascia

MSDN Magazine June 2005

...

Read more!

Popular Articles

Jason Clark

MSDN Magazine July 2003

...

Read more!

A Sidebar gadget is a powerful little too that's surprisingly easy to create. Get in on the fun with Donavon West.

Donavon West

MSDN Magazine August 2007

...

Read more!

One-time passwords offer solutions to dictionary attacks, phishing, interception, and lots of other security breaches. Here's how it all works.

Dan Griffin

MSDN Magazine May 2008

...

Read more!

Jeff Prosise explains when it's better to use UpdatePanel and when it's better to use asynchronous calls to WebMethods or page methods instead.

Jeff Prosise

MSDN Magazine June 2007

...

Read more!

Learn how to automate custom SharePoint application deployments, use the SharePoint API, and avoid the hassle of custom site definitions.

E. Wilansky, P. Olszewski, and R. Sneddon

MSDN Magazine May 2008

...

Read more!

Our Blog

So many factors can affect the performance of a Web page—the distance between server and client, the size of the elements on the page, how the browser loads these elements, available bandwidth. Finding those bottlenecks and identifying the culprits is no easy task.

In the November 2008 issue of MSDN Magazine, Jim Pierson introduces ...

Read more!

Visual Studio 2008 Team Foundation Server Build (better known as Team Build) is a core feature of Team Foundation Server 2008. Microsoft designed Team Build to be an industrial-strength build automation tool.

In the November 2008 issue of MSDN Magazine, Brian A. Randell introduces you to Team Build 2008 and walks you through the process ...

Read more!

It’s helpful to think about secure design from a more holistic perspective by using threat models to drive your security engineering process.

In the November 2008 issue of MSDN Magazine, Michael Howard proposes using the threat model to help drive other SDL security requirements, primarily code review priority, fuzz testing priority, ...

Read more!

Because Windows Workflow Foundation (WF) is based on a runtime that manages the execution of workflows and activities, testing must, in almost all cases, involve the use of the runtime – and this can introduce some interesting challenges.

In the November 2008 issue of MSDN Magazine, Matt Milner presents some techniques for unit testing ...

Read more!

Earlier this year MSDN Magazine embarked on a collaborative project with Behind the Code, an interview program airing on MSDN Channel 9. In this program, Robert Hess interviews prominent developers at Microsoft, and those developers also write a column for { End Bracket } in MSDN Magazine. In the newest interview, Richard Ward talks about working on the core infrastructure components of future versions of Windows, as well as ...

Read more!

C++ At Work
Event Programming, Part 2
Paul DiLascia

Code download available at: CAtWork0603.exe (3,178 KB)
Browse the Code Online

Last month I answered a question about implementing native events in C++ (see C++ At Work: Event Programming). I discussed events in general and showed how to use an interface to define event handlers for your class that clients must implement to handle events. My implementation had some shortcomings that I promised to resolve in the sequel, so here I am to finish the story.
Figure 1 Calculating Prime Numbers 
But first, a brief review of the previous episode. I wrote a program, PrimeCalc (Figure 1), with a class CPrimeCalculator that calculates prime numbers. CPrimeCalculator raises two events: Progress and Done. As it searches for prime numbers, CPrimeCalculator raises the Progress event to report how many primes it's found so far. When it's finished, it raises the Done event. The events are defined by an interface, IPrimeEvents:
class IPrimeEvents {
public:
  virtual void OnProgress(UINT nPrimes) = 0;
  virtual void OnDone() = 0;
};
Clients that want to handle prime events must derive from IPrimeEvents, implement the handler functions, and call CPrimeCalculator::Register to register their interface. CPrimeCalculator::Register adds the client object/interface to its internal list. When it's time to raise a Progress event, CPrimeCalculator calls a helper function NotifyProgress:
void CPrimeCalculator::NotifyProgress(UINT nFound)
{
  list<IPrimeEvents*>::iterator it;
  for (it=m_clients.begin(); it!=m_clients.end(); it++) {
    (*it)->OnProgress(nFound);
  }
}
NotifyProgress walks the client list, calling each client's OnProgress handler. As a programmer using CPrimeCalculator, writing the code to handle events is straightforward and easy—just derive from IPrimeEvents and implement the handlers. But as a programmer implementing a class like CPrimeCalculator that raises events, the mechanism is tedious. You have to implement a NotifyFoo function for every Foo event, even though each one has the same familiar pattern. And the event-raising code is split across two classes, the event interface (IPrimeEvents) and the event source class (CPrimeCalculator). What if you want to use the same event interface with different event sources? IPrimeEvents is pretty generic. I might rename it IProgressEvents and use it with any worker class that reports Progress in the form of an integer and Done when it's finished. But each class that raises progress events has to (re)implement the notification functions that raise the event. Ideally, all the event code should reside in a single class.
Since the notification functions follow a predictable pattern, it's natural to ask: Isn't there some way to implement them generically? Shouldn't I be able to encapsulate the entire event mechanism in a single class or template or macro or something any event source can use? The answers are yes and yes. I'll show you how to create an event system that uses macros and templates to reduce event coding to the barest minimum. Our journey requires flying high into the C++ stratosphere of nested templates and functor classes.
I'll implement the system in several steps. The goal is to write a template that implements the notification functions NotifyProgress and NotifyDone. Each function has a similar but not identical pattern:
// NotifyFoo — raise Foo event
list<IPrimeEvents*>::iterator it;
for (it=m_clients.begin(); it!=m_clients.end(); it++) {
  (*it)->OnFoo(/*args*/);
}
That is, iterate the client list, and call OnFoo for each client, passing the event parameters. How can I write this as a template? I can parameterize the interface IPrimeEvents as a type T, but how do I parameterize the event handler functions OnFoo, which can have any name and signature a programmer chooses?
Whenever you need to parameterize a function, you should think: function class. Also known as a functor, a function class is a C++ sleight-of-hand trick that converts a function to a class, so instead of passing a pointer to a callback function, you pass an instance of the function class. Functors abound in the Standard Template Library (STL), which implements several algorithms that use functors. In particular, the for_each algorithm is useful here:
for_each(m_clients.begin(), m_clients.end(),
  NotifyProgress(nFound));
The for_each algorithm iterates the container from beginning to end and invokes the function object NotifyProgress for each element. But what exactly is this "function object"? It's not a function; it's an object. The class looks like this:
class NotifyProgress {
protected:
  UINT m_nFound;
public:
  NotifyProgress(UINT n) : nFound(n) { }
  void operator()(IPrimeEvents* obj)
  {
    obj->OnProgress(nFound);
  }
};
NotifyProgress implements the function operator()(IPrimeEvents*), which is what the for_each algorithm needs. In general, if you have a collection of objects of type T, the for_each algorithm expects a functor that implements operator()(T). It calls your operator with each T object in the collection. So in this case the function operator takes a pointer to IPrimeEvents and returns void—because the client list is a list of pointers-to-IPrimeEvents. To pass additional parameters, the constructor stores them as data members. Calling NotifyProgress(nFound) is calling the constructor to create a stack instance initialized with m_nFound=nFound. So the general pattern for any Foo functor that raises the Foo event is:
class NotifyFoo {
protected:
  ARG1 m_arg1; // whatever, as many as needed
public:
  NotifyProgress(ARG1 a1, ...) : m_arg1(a1) { }
  void operator()(IMyEvents* obj)
  {
    obj->OnFoo(m_arg1, ...);
  }
};
The constructor saves the event parameters as data members and the function operator passes them to the object's event handler function. The upshot of all this—and of all functors in general—is that I've converted a function OnFoo into a class NotifyFoo. And why is that useful? Because now I can write a template. But before I do that, there's one little thing I want to mention. To earn your gold star, you really should derive your functor from an STL class called unary_function:
class NotifyProgress : 
  public unary_function<IPrimeEvents*, void> 
{
  .
  . // as before
  .
};
This says that NotifyProgress is a unary function whose function operator takes one argument, a pointer-to-IPrimeEvents, and returns void. The unary_function makes your functor class "adaptable," which lets you combine it with STL adapters like not1, bind2nd, and so on. But even if, as is the case with my event handlers, you never plan to use adapters, unary_function is still a good idea because it announces to the world, "this is a functor." It's a way of documenting your code. For a full discussion of adapters, see Effective STL: 50 Specific Ways to Improve Your Use of the Standard Template Library (Addison-Wesley, 2001) by Scott Meyers.
STL gurus may be wondering why I don't use the mem_fun adapter to convert IPrimeEvents::OnProgress directly to a function object. It's because OnProgress is virtual and you can't adapt a virtual function. If you do, it'll get sliced to the base class. If you're using the Boost library, you could use its bind adapter to directly convert virtual event handlers like OnFoo to functors without writing a functor. If you have no idea what I'm talking about, don't fret, just keep reading.
Of course, I also need a NotifyDone for the Done event. Since the Done event has no parameters, the constructor has none either:
class NotifyDone :
  public unary_function<IPrimeEvents*, void> 
{
public:
  NotifyDone() { }
  void operator()(IPrimeEvents* obj)
  {
    obj->OnDone();
  }
};
So now that I have my functor classes I can use for_each instead of manually iterating the client list. Where should I put them? The functors belong with the event specification, so I'll put them inside IPrimeEvents, as nested classes. Figure 2 shows the code. Astute readers will notice I've made a couple of other minor modifications as well. Instead of naming the functor NotifyProgress, I called it Progress. You'll see how this makes the code more readable later. And instead of declaring all my event handlers pure, I've defined them with empty implementations. IPrimeEvents has only two events, but for a general event mechanism, it seems unfriendly to make programmers implement every event handler when they may be interested in handling only a few. So now each handler gets a default do-nothing implementation. To make the base class abstract, I've declared the destructor pure. This is a standard C++ trick when you want to make a class abstract without having any pure virtual functions. The only catch is you have to define the dtor. A pure virtual function has no definition—unless it's the destructor. Since each derived class dtor calls its base class dtor, the base class needs an implementation even though it's pure:
inline IPrimeEvents::~IPrimeEvents() { }
Now with my functors defined, CPrimeCalculator raises the Progress event, like so:
// in CPrimeCalculator:
void NotifyProgress(UINT nFound)
{
  for_each(m_clients.begin(), m_clients.end(),
    IPrimeEvents::Progress(nFound));
}
/////////////////
// Interface for prime events. This class defines the signatures
// of the event handler functions as well as nested functor 
// classes to use with for_each. Clients that handle prime events must 
// derive from this and override the event handlers for events they 
// handle. 
//
class IPrimeEvents {
protected:
    IPrimeEvents() { }
    virtual ~IPrimeEvents() = 0;

public:
    // Virtual event handler fns. Override the ones you handle.
    virtual void OnProgress(UINT /* nPrimes */) { }
    virtual void OnDone() { }

    // Nested functor class for Progress event. Note how the ctor requires
    // the same parameters as the event handler and stores them in the 
    // object.
    class Progress : public unary_function<IPrimeEvents*, void> {
    protected:
        UINT nFound;
    public:
        Progress(UINT n) : nFound(n) { }
        void operator()(IPrimeEvents* obj)
        {
            obj->OnProgress(nFound);
        }
    };
    
    // Nested functor class for Done event. This time there are no event 
    // args.
    class Done : public unary_function<IPrimeEvents*, void> {
    public:
        Done() { }
        void operator()(IPrimeEvents* obj)
        {
            obj->OnDone();
        }
    };
};

inline IPrimeEvents::~IPrimeEvents() { }

// List (vector) of prime numbers.
typedef vector<UINT> PRIMELIST;

//////////////////////////////////////////////////////////////////
// Class to calculate 1st n prime numbers.
//
class CPrimeCalculator
{
protected:
    list<IPrimeEvents*> m_clients;     // list of client objects to notify
    PRIMELIST m_primes;            // list (vector) of primes numbers found

    // Raise events. Use for_each with function class.
    void NotifyProgress(UINT nFound)
    {
        for_each(m_clients.begin(), m_clients.end(),
            IPrimeEvents::Progress(nFound));
    }

    void NotifyDone()
    {
        for_each(m_clients.begin(), m_clients.end(),
            IPrimeEvents::Done() );
    }

    ...
};
So far, I've introduced functor classes Progress and Done, and now NotifyProgress and NotifyDone can use STL's for_each algorithm. What next? Remember, my goal is to get rid of the NotifyFoo functions entirely—or rather, implement them as templates so programmers creating events don't have to write these boilerplate functions for every event they define. Converting the for loop to a for_each algorithm is only the first step.
The functors set the stage for templates by converting the virtual OnFoo member function to a Foo functor type. (Functors are a bit like .NET delegates in this respect.) Now that my notification functions vary by type instead of function names, I can parameterize them. And when I do that, I can move the whole event implementation out of the source class CPrimeCalculator and into a new template class CEventMgr that's totally generic. Figure 3 shows the result. CEventMgr<I> holds a list of I* pointers. It has Register and Unregister methods to add and remove clients from its list, and it has a template member function Raise that raises an event:
template <typename I>
class CEventMgr
{
  ...
  template <typename F>
  void Raise(F fn)
  {
    for_each(m_clients.begin(), m_clients.end(), fn);
  }
};
////////////////////////////////////////////////////////////////
// Generic event manager for native C++.
//
#pragma once

#include <list>
#include <algorithm>
using namespace std;

//////////////////
// Generic event manager. Holds list of client objects. Template class
// parameterized by the event interface.
//
// - Instantiate in event source class.
//
// - Source calls Raise to raise an event, passing functor object 
// initialized with event params.
//
// - Clients derive from event interface and override event handlers. 
// Clients call Register/Unregister to add/remove themselves.
//
template <typename I>
class CEventMgr
{
protected:
    list<I*> m_clients; // list of registered client objects
public:
    CEventMgr() { }
    ~CEventMgr() { }

    // Register: Add client to list.
    void Register(I* client)
    {
        m_clients.push_back(client);
    }

    // Unregiser: Remove client from list.
    void Unregister(I* client)
    {
        m_clients.remove(client);
    }

    // Nested template member function! This fn calls the function object 
    // F for each registered client. It merely passes F to for_each. Use 
    // the DEFINE_EVENT macros to generate the functors. See IPrimeEvents 
    // in Prime.h for example. 
    template <typename F>
    void Raise(F fn)
    {
        for_each(m_clients.begin(), m_clients.end(), fn);
    }
};

// Macro to declare an event interface. Generates declarations for ctor/dtor.
#define DECLARE_EVENTS(name)                                            \
protected:                                                              \
    name() { }                                                          \
    virtual ~name() = 0;                                                \

// Macro to implement event interface. Defines dtor
#define IMPLEMENT_EVENTS(name)                                          \
    inline name::~name() { }                                            \

// Macros to define events that use 0, 1 or 2 parameters. If you need more
// than two, you should define a struct/class and pass a pointer to it.

// Event with no args: Declare OnFoo handler and Foo functor.
#define DEFINE_EVENT0(iface,name)                                 \
virtual void On##name() { };                                      \
class name : public unary_function<iface*, void> {                \
public:                                                           \
    name() { }                                                    \
    void operator()(iface* obj)                                   \
    {                                                             \
        obj->On##name();                                          \
    }                                                             \
};                                                                \

// Event with one arg: Declare OnFoo handler and Foo functor.
#define DEFINE_EVENT1(iface,name,T1)                              \
virtual void On##name(T1) { }                                     \
class name : public unary_function<iface*, void> {                \
protected:                                                        \
    T1 m_arg1;                                                    \
public:                                                           \
    name(T1 a1) : m_arg1(a1) { }                                  \
    void operator()(iface* obj)                                   \
    {                                                             \
        obj->On##name(m_arg1);                                    \
    }                                                             \
};                                                                \

// Event with two args: Declare OnFoo handler and Foo functor.
#define DEFINE_EVENT2(iface,name,T1,T2)                           \
virtual void On##name(T1, T2) { }                                 \
class name : public unary_function<iface*, void> {                \
protected:                                                        \
    T1 m_arg1;                                                    \
    T2 m_arg2;                                                    \
public:                                                           \
    name(T1 a1, T2 a2) : m_arg1(a1), m_arg2(a2) { }               \
    void operator()(iface* obj)                                   \
    {                                                             \
        obj->On##name(m_arg1, m_arg2);                            \
    }                                                             \
};                                                                \
Holy cow, Batman! How often do you get to write a template-within-a-template? But that's just what's required here. Now to raise an event I can write:
void NotifyProgress(UINT nFound)
{
  m_eventmgr.Raise(IPrimeEvents::Progress(nFound));
}
That's more like it! No for loop, not even a for_each. All the details are encapsulated in CEventMgr, and raising an event is one line of code that knows nothing about the mechanics. I could even dispense with NotifyProgress entirely and simply call CEventMgr::Raise when I want to raise an event—but good coding ethics prevent me because I'd rather encapsulate Raise in a function in case I ever change CEventMgr or expose the event-raising function to clients. Since NotifyProgress is inline, there's no performance lost.
In case templates make your brain hurt, let me spell out what's going on. CEventMgr is a template class parameterized by the event interface I. So CEventMgr<IPrimeEvents> instantiates an event manager based on IPrimeEvents. It holds a data member m_clients, which is a list of IPrimeEvents pointers, list<IPrimeEvents*>. Within CEventMgr is a template member function, Raise<F>, which passes its functor argument F to for_each. So when you write
m_eventmgr.Raise(IPrimeEvents::Progress(nFound));
the compiler sees you're trying to call CEventMgr::Raise with an argument of type IPrimeEvents::Progress, so it uses the template to generate the member function CEventMgr::Raise(IPrimeEvents::Progress). The implementation passes the functor instance to for_each, which invokes the functor's function operator() for each I* object in the client list. The functor calls the object's OnProgress handler—just what I wanted! Aren't templates cool?
We've reached third base, we're almost home. The functors let me parameterize the event methods and use for_each, but they're still several lines long and I so hate typing. So the final step is to introduce some macros to spare my carpal tunnels. Here's the final condensed definition for IPrimeEvents:
class IPrimeEvents {
  DECLARE_EVENTS(IPrimeEvents);
public:
  DEFINE_EVENT1(IPrimeEvents, Progress, UINT /*nFound*/);
  DEFINE_EVENT0(IPrimeEvents, Done);
};
IMPLEMENT_EVENTS(IPrimeEvents);
Figure 4 shows the full code—you can see I'd be hard pressed to condense it any further. Only the essential information appears: the names and signatures for each event handler. The macros assume the name of the Foo event handler is OnFoo. Some programming purists hate macros, but not me. Why not use every tool at your disposal? DECLARE_EVENTS declares the constructor and destructor; IMPLEMENT_EVENTS implements the inline dtor. The macros DEFINE_EVENT0, DEFINE_EVENT1, and DEFINE_EVENT2 declare/define the OnFoo event handlers and Foo functors for events with zero, one, or two parameters. If you need more than two parameters, you can define a struct and pass a pointer to it as a single event parameter:
MumbleArgs args;
args.a = 1;
args.b = 2;
// etc.
m_eventMgr.Raise(IMyEvents::Mumble(&args));
// Now the whole thing is defined with macros.
//
class IPrimeEvents {
    DECLARE_EVENTS(IPrimeEvents);
public:
    DEFINE_EVENT1(IPrimeEvents, Progress, UINT /*nFound*/);
    DEFINE_EVENT0(IPrimeEvents, Done);
};

IMPLEMENT_EVENTS(IPrimeEvents);

// List (vector) of prime numbers.
typedef vector<UINT> PRIMELIST;

//////////////////////////////////////////////////////////////////
// Class to calculate 1st n prime numbers.
//
class CPrimeCalculator
{
protected:
    CEventMgr<IPrimeEvents> m_eventmgr;     // instantiate general event manager
    PRIMELIST m_primes;         // list (vector) of primes numbers found

    ...

    // Raise events. The notification functions simply call
    // CEventMgr::Raise with the appropriate functor object.
    void NotifyProgress(UINT nFound)
    {
        m_eventmgr.Raise(IPrimeEvents::Progress(nFound));
    }

    // Notify clients I'm Done.
    void NotifyDone()
    {
        m_eventmgr.Raise(IPrimeEvents::Done());
    }

public:

    // Register client to receive events
    void Register(IPrimeEvents* client)
    {
        m_eventmgr.Register(client);
    }

    // Unregister client from receiving events.
    void Unregister(IPrimeEvents* client)
    {
        m_eventmgr.Unregister(client);
    }
};
Alternatively, you could implement DEFINE_EVENT3. But remember: functor objects are passed by value, so they should be small. Why copy a ton of parameters back and forth across the heap and stack when you can pass a pointer instead? You can also use a struct if your event handlers need to return something. I made the handler functions return void in order to simplify my life.
Programmers sometimes ask if functors introduce a lot of extra overhead. In fact, functors are usually more efficient than functions. The reason is inlining. When you pass a pointer-to-function in C++, it really is a pointer, even if you define your function inline. You can't pass a function by value. But when you pass an object instance to a template function, the compiler can generate everything inline if you define your functions that way. In the case of events, there's still only one function call through a pointer, which happens when the function operator invokes the virtual OnFoo handler.
Happy programming!

Send your questions and comments for Paul to  cppqa@microsoft.com.


Paul DiLascia is a freelance software consultant and Web/UI designer-at-large. He is the author of Windows++: Writing Reusable Windows Code in C++ (Addison-Wesley, 1992). In his spare time, Paul develops PixieLib, an MFC class library available from his Web site, www.dilascia.com.

Page view tracker