我有一个 Node 类模板,它采用 Data 类型作为模板参数:
template <class T_Data>
class Node
{
};
Node 类能够在某些事件上通知用户/侦听器。此功能是使用libsigc++
信号实现的,但在发出信号之前,节点会通知处理程序对象,该处理程序对象会进行一些处理并决定是否发出信号。这个处理程序对象存在是因为在某些情况下我希望节点对象处理它们的 oen 事件,阻塞信号。
常见的解决方案是为 Node 提供任何人都可以在派生类中覆盖的虚拟方法,但由于 Node 使用对自身的引用并创建自己类型的对象,因此拥有 HandlerBase 类并让人们派生处理程序会更容易。
一切都很顺利,直到我编写了一个处理程序类并且我希望我的节点使用它。但是为了启用新的处理程序,我需要调用一个静态 Node 方法,Node::set_event_handler()
. 这意味着我必须记住在某个地方调用它。如果有人想使用我的处理程序,他们必须记住在 main() 或某个主类的 ctor 中设置处理程序,也许是他们在 GUI 应用程序中的 Window 类。
template <class T_Data>
class Node
{
public:
static void set_event_handler (std::unique_ptr <HandlerBase> new_handler);
private:
static std::unique_ptr <HandlerBase> event_handler;
};
所以我想出了两个可能的解决方案:
- 将电话放在
set_handler()
我的一些主要课程中 - 将 T_Handler 模板参数添加到 Node 类
目前,静态处理程序字段设置为一个新的 HanderBase,它忽略所有信号。如果我使用模板参数,可能会有相同的数据类型与不同的处理程序,并且在初始化时会设置静态字段,因此不需要额外的工作。
问题是,T_Handler 是否不只是给 Node 添加了“混乱”,在为处理程序类型添加模板参数的意义上使其变得不那么“干净”,许多 Node 用户甚至不需要。
实际上,我也可以给 T_Handler 一个默认值,这样用户就可以忘记它,因为他们不需要它,但我仍然很好奇哪种设计可能更好。