事件系统类似于C#(.NET?)

时间:2013-05-17 16:25:42

标签: c++ events event-handling

在C#中(至少使用.NET,但我认为这是一般的),你可以创建这样的事件:Understanding events and event handlers in C#

C ++有类似的机制吗?

PS:我从来都不喜欢信号/插槽系统,所以请不要建议,因为我已经在使用它,并希望切换到别的东西。

3 个答案:

答案 0 :(得分:6)

C#中的事件机制实际上只是Observer Pattern的正式语言实现版本。这种模式可以用任何语言实现,包括C ++。 implementations in C++有很多例子。

最大且最常见的实现可能是Boost.SignalsBoost.Signals2,尽管您明确提到不喜欢信号/插槽样式实现。

答案 1 :(得分:1)

可以从下面的链接下载Event.h,它提供了一个用C ++实现的类似.NET的事件:http://www.codeproject.com/Tips/1069718/Sharp-Tools-A-NET-like-Event-in-Cplusplus

其用法示例:

#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
}

答案 2 :(得分:0)

如果不能选择boost,我用c ++ here实现了事件。语义与.NET几乎相同。它是一个紧凑的实现,但使用了相当高级的C ++特性:需要一个现代的C ++ 11编译器。