2013-05-03 82 views
1

我有一個節點類模板,這需要一個數據類型作爲模板參數: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; 
}; 

於是我想出了兩種可能的解決方案:

  1. 將調用set_handler()在一些主要的I類有
  2. 一個T_Handler模​​板參數添加到Node類

目前,靜態處理程序字段被設置爲一個新的HanderBase,它會忽略所有的信號。如果我使用模板參數,可以使用不同處理程序的相同數據類型,並且靜態字段將在初始化中設置,因此不需要額外的工作。

問題是,T_Handler是否不僅僅爲節點添加「混亂」,使得它僅僅爲處理程序類型添加模板參數(它並非許多節點用戶甚至不需要)而不那麼「乾淨」。其實,我也可以給T_Handler一個默認值,這樣用戶就可以忘記它不需要它,但我仍然好奇哪種設計可能更好。

回答

1

當然,它增加了混亂,並使其不那麼幹淨。但是,這真的是一個大問題嗎?這取決於你的觀點,我想。

如果您查看標準庫中的許多模板,您將看到大多數用戶不需要的模板參數。默認值以及typedef用於隱藏這種混亂。例如,看std::basic_string,其中:

  • 大多數用戶並不關心traitsAlloc,所以有默認值這些參數
  • charT一個流行的值就是char,所以std::string型被定義爲速記。

請注意,這種混亂只是隱藏。如果你需要調試你的代碼,並且你正在調試器中查看變量的類型,它會出來咬你。;)