我有一個節點類模板,這需要一個數據類型作爲模板參數:C++類設計建議
template <class T_Data>
class Node
{
};
Node類能夠通知關於某些事件的用戶/收聽者。該功能是使用libsigc++
信號實現的,但是在發出信號之前,Node會通知一個處理器對象,它執行一些處理並決定是否發出信號。此處理程序對象存在,因爲在某些情況下,我希望節點對象處理它們的事件,阻止信號。
通常的解決方案是給Node提供一個虛擬方法,任何人都可以在派生類中重寫,但是由於Node使用對自身的引用並創建自己類型的對象,因此擁有HandlerBase類並讓人派生處理程序。
一切都很好,直到我寫一個處理程序類,我希望我的節點使用它。但爲了啓用新的處理程序,我需要調用靜態節點方法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()
在一些主要的I類有 - 一個T_Handler模板參數添加到Node類
目前,靜態處理程序字段被設置爲一個新的HanderBase,它會忽略所有的信號。如果我使用模板參數,可以使用不同處理程序的相同數據類型,並且靜態字段將在初始化中設置,因此不需要額外的工作。
問題是,T_Handler是否不僅僅爲節點添加「混亂」,使得它僅僅爲處理程序類型添加模板參數(它並非許多節點用戶甚至不需要)而不那麼「乾淨」。其實,我也可以給T_Handler一個默認值,這樣用戶就可以忘記它不需要它,但我仍然好奇哪種設計可能更好。