2010-02-18 88 views
0

我正在創建一個按鈕類,並且在2個解決方案之間很難做出決定。模板與操作層次

1)對模板Button進行模板化,並讓它在構造函數中使用一個函數對象,以便在按下按鈕時進行調用。我正在編碼的人擔心這會導致代碼膨脹/顛簸。

2)創建一個ButtonAction基類,每個按鈕都會有不同的ButtonAction。因此,Button類在其構造函數中使用ButtonAction來在按下按鈕時進行調用。

我們也考慮過函數指針的使用,但並沒有完全想到它。

+0

兩個是可接受的解決方你關心什麼樣的標準?第二種形式可能會更可讀,但肯定更羅嗦。我相信你可以在沒有模板的情況下實現第一個解 – Pace 2010-02-18 04:07:08

回答

5

您可以使用boost::function<>對象進行操作。這樣,你不需要任何模板和按鈕類變得非常靈活:

struct Button { 
    typedef boost::function<void()> action_t; 
    action_t action; 

    Button(const action_t &a_action) : action(a_action) { 
    } 

    void click() { 
     action(); 
    } 
}; 

這樣的類很容易與函數指針,仿函數對象或事物使用像boost::bind

void dosomething(); 
Button b1 = Button(&dosomething); 

struct SomeAction { 
    void operator()() {} 
}; 
Button b2 = Button(SomeAction()); 
+1

+1,同樣考慮到在許多框架中,您可以將多個動作連接到單個按鈕。如果你想在某個點或另一個點提供該功能,只需要將你的內部類型改爲'boost :: signal '並調用'.connect'而不是將該動作分配給'boost :: function <>'目的 – 2010-02-18 08:42:39

1

我列舉了每個備選方案的後果,然後決定哪個選項最適合特定情況。

如果模板選項可能(過早擔心?)膨脹目標代碼,那麼多態替代可能會使源代碼不必要的複雜。

對於模板,編譯器將爲您實例化的每個函數對象創建另一個Button類。這意味着產品目標代碼將比通過子類接受各種操作對象的單個Button類更大。

在多態性的情況下,編譯器將生成一個單一的Button類,但您現在將擁有另一個基類來維護,並且您將被強制爲其添加到集合的任何新操作進行子類化。特別是你不能使用在你創建基類動作類之前編寫的動作,除非你可以修改它們,使它們從動作類派生。

模板替代方案允許您使用任何符合模板界面的任何東西。所以如果你使用模板參數作爲函數,那麼你可以接受任何可以被稱爲函數的東西。這意味着你甚至不需要考慮函數指針的選擇,因爲模板允許你接受函數指針 - 等等。

多態選項意味着編譯器知道更多關於你想要做什麼。換句話說,模板帶有模板錯誤。

如果您可以找到一種方法來模板Button成員函數,而不是整個Button類,則可以緩解一些模板問題。以函數參數作爲模板的一個實例,因此不需要顯式實例化模板函數。然後你贏得了一些模板的好處,以及一些多態性的好處。