6

In C# (at least using .NET, but I think it's general), you can create events like this: Understanding events and event handlers in C#.

Is there a similar mechanism for C++?

PS: I've never liked signal/slot system, so please don't suggest it, since I'm already using it and would love to switch to something else.

cbuchart
  • 10,847
  • 9
  • 53
  • 93

3 Answers3

6

The event mechanism in C# is really just a formal, language implemented version of the Observer Pattern. This pattern can be implemented in any language, including C++. There are many examples of implementations in C++.

The largest and most common implementation is probably Boost.Signals and Boost.Signals2, though you explicitly mentioned not liking the signal/slot style implementations.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • 1
    You could also look at std::function which allows function objects to be used in the same way and is part of the C++11 standard. See here: http://oopscenities.net/2012/02/24/c11-stdfunction-and-stdbind/ – Pat Mustard May 20 '13 at 01:43
1

Event.h can be downloaded from the link bellow, it provides a .NET like Event implemented in C++: http://www.codeproject.com/Tips/1069718/Sharp-Tools-A-NET-like-Event-in-Cplusplus

An example of its usage:

#include "Event.h"  // This lib consists of only one file, just copy it and include it in your code.

// an example of an application-level component which perform part of the business logic
class Cashier
{
public:
  Sharp::Event<void> ShiftStarted;  // an event that pass no argument when raised
  Sharp::Event<int> MoneyPaid;  // will be raised whenever the cashier receives money

  void Start();  // called on startup, perform business logic and eventually calls ProcessPayment()

private:
  // somewhere along the logic of this class
  void ProcessPayment(int amount)
  {
    // after some processing
    MoneyPaid(amount);  // this how we raise the event
  }
};

// Another application-level component
class Accountant
{
public:
  void OnMoneyPaid(int& amount);
};

// The main class that decide on the events flow (who handles which events)
// it is also the owner of the application-level components
class Program
{
  // the utility level components(if any)
  //(commented)DataStore databaseConnection;

  // the application-level components
  Cashier cashier1;
  Accountant accountant1;
  //(commented)AttendanceManager attMan(&databaseConnection) // an example of injecting a utility object

public:
  Program()
  {
    // connect the events of the application-level components to their handlers
    cashier1.MoneyPaid += Sharp::EventHandler::Bind( &Accountant::OnMoneyPaid, &accountant1);
  }

  ~Program()
  {
    // it is recommended to always connect the event handlers in the constructor 
    // and disconnect in the destructor
    cashier1.MoneyPaid -= Sharp::EventHandler::Bind( &Accountant::OnMoneyPaid, &accountant1);
  }

  void Start()
  {
    // start business logic, maybe tell all cashiers to start their shift
    cashier1.Start();
  }
};

void main()
{
  Program theProgram;
  theProgram.Start();

  // as you can see the Cashier and the Accountant know nothing about each other
  // You can even remove the Accountant class without affecting the system
  // You can add new components (ex: AttendanceManager) without affecting the system
  // all you need to change is the part where you connect/disconnect the events
}
AmerS
  • 88
  • 5
0

If boost is not an option, I implemented events in c++ here. The semantics is almost the same as in .NET . It's a compact implementation but uses quite advanced C++ features: a modern C++11 compiler is required.

ceztko
  • 14,736
  • 5
  • 58
  • 73