我有一个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()
的电话放在我有的主要班级目前,静态处理程序字段设置为新的HanderBase,忽略所有信号。如果我使用模板参数,则可以使用不同的处理程序具有相同的数据类型,并且将在初始化中设置静态字段,因此不需要额外的工作。
问题是,T_Handler是否不只是为Node添加“混乱”,使得它更少“干净”,只是为处理程序类型添加模板参数,许多Node用户甚至都不需要。< / p>
实际上,我也可以给T_Handler一个默认值,这样用户可以忘记它们不需要它,但我仍然很好奇哪种设计可能更好。
答案 0 :(得分:1)
当然,它会增加杂乱,使其不那么干净。但是,它真的是一个大问题吗?我想这取决于你的观点。
如果查看标准库中的许多模板,您将看到大多数用户不需要的模板参数。默认值以及typedef
用于隐藏此混乱。例如,请参阅std::basic_string,其中:
traits
或Alloc
,因此这些参数有默认值charT
的热门价值仅为char
,因此std::string类型定义为速记。请注意,这种混乱只是隐藏的。如果您需要调试代码并且在调试器中查看变量的类型,它会引发您的兴趣。 ;)