【问题标题】:C++ event system - using heap or stack based eventsC++ 事件系统 - 使用基于堆或堆栈的事件
【发布时间】:2012-11-15 14:26:57
【问题描述】:

我正在尝试设计一个简单的事件系统,“基本上”看起来像这样:

  • 观察者 实体保存所有需要通知的对象的列表。它还存储触发事件的队列。事件随后由对象列表处理,遍历此对象列表。
  • 一个对象保存了一个它发送事件的观察者列表。从基础对象继承的每个特定对象都可以触发其自己的专用事件(键、鼠标、碰撞等)。该对象还有一个方法HandleEvent(..),具有不同的重载用于编译时类型检测,而不是使用dynamic_casting

在触发事件时最好选择什么:在堆栈上创建它们并通过引用传递它们,或者在堆上动态分配它们并使用 dynamic_casting 并让观察者在它们被对象处理时释放它们可以处理它们吗? (例如,当一个事件可以经常被触发时,动态分配是不是不必要的;动态转换呢,不是可以避免的吗?)。

另外,这不是一个线程安全的场景..

【问题讨论】:

  • 请澄清您所说的“这不是一个线程安全的场景”的意思
  • 我担心在堆栈上声明对象(例如函数体中的事件)在多线程场景中可能是一个坏主意,因为这些对象在处理时可能会被销毁由另一个线程。
  • 嗯,你是对的。但是,在您所写的场景中,您都没有使用基于堆栈的分配。
  • 哦,对不起,你是对的,我看到在同一个短语中使用了双重“在堆上创建它们”句子。
  • 太好了,谢谢,这让它更清楚了。

标签: c++ design-patterns event-handling


【解决方案1】:

您需要动态分配吗?不。通常,你想要

void fireEvent()
{
    Event ev;
    for ( each observer )
       observer.trigger(ev);
}

还有观察者的签名

void trigger(const Event& ev);

请注意,从迂腐的角度来说,“传递对它们的引用”是不正确的。它实际上是“通过引用传递它们”。

【讨论】:

  • 备注备注;如果这是一个线程场景,触发器函数尝试注入各种处理程序的事件会发生什么? (假设触发是在不同的线程上执行的?)。
  • 主要原因是,虽然堆栈管理对象通常在分配速度方面比堆管理对象更可取,但如果尝试使用多个线程,引用可能会损坏。
  • 触发器可以尝试传递一个曾经存在于堆栈中的对象,但在 void fireEvent() 方法退出时被销毁。或者这不是标准行为吗? (我可能很困惑..)
猜你喜欢
  • 2021-11-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2011-02-25
  • 2014-07-21
  • 2020-06-05
  • 2020-12-24
  • 1970-01-01
相关资源
最近更新 更多