我的C++框架有按鈕。一個Button派生自Control。所以接受Control的函數可以將Button作爲參數。到現在爲止還挺好。C++模板和繼承
我也有名單<
T>。但是,列表<
按鈕>並非從List <
Control>派生,這意味着接受控件列表的函數不能將Button列表作爲其參數。這很不幸。
也許這是一個愚蠢的問題,但我不知道怎樣才能解決這個:(名單<
按鈕>
應該從列表<
控制>
得出,但我不明白的方式來做到這一點「自動」
我的C++框架有按鈕。一個Button派生自Control。所以接受Control的函數可以將Button作爲參數。到現在爲止還挺好。C++模板和繼承
我也有名單<
T>。但是,列表<
按鈕>並非從List <
Control>派生,這意味着接受控件列表的函數不能將Button列表作爲其參數。這很不幸。
也許這是一個愚蠢的問題,但我不知道怎樣才能解決這個:(名單<
按鈕>
應該從列表<
控制>
得出,但我不明白的方式來做到這一點「自動」
我不想告訴你,但是如果你正在使用實例列表來控制,而不是指向Control的指針,你的按鈕無論如何都是垃圾(谷歌「對象切片」)。如果它們是指針列表,則可以按照其他人的建議將list<button*>
轉換爲list<control*>
,或者從list<button*>
複製到新的list<control*>
,並將即代入該函數。或者將該函數重寫爲模板。
所以,如果你以前有一個叫做DoSomething的功能了一個列表控件作爲參數,你把它改寫爲:
template <class TControl>
void doSomething(const std::list<TControl*>& myControls) {
... whatever the function is currently doing ...
}
void doSomethingElse() {
std::list<Button*> buttons;
std::list<Control*> controls;
doSomething(buttons);
doSomething(controls);
}
如何使用指針?只是有list<Control*>
列表,把你喜歡到它的任何控制派生的對象。
而不是使用列表<按鈕>,使用列表<控制* >的,這是指向按鈕。這樣,你的功能只有採取一種類型:列表<控制* >。
斯特勞斯對這個項目在他的FAQ:
Why can't I assign a vector<Apple*>
to a vector<Fruit*>
您可以通過兩種方式解決這個問題:
Control
。然後接受List<Control*>
List<Button>
和List<Control>
,但它更多的是樣板代碼,而且絕大多數時候不需要考慮。這裏是第二個選擇的代碼。第一種選擇已經由其他答案解釋:
class MyWindow {
template<typename T>
void doSomething(List<T> & l) {
// do something with the list...
if(boost::is_same<Control, T>::value) {
// special casing Control
} else if(boost::is_same<Button, T>::value) {
// special casing Button
}
}
};
要只爲List<derived from Control>
限制doSomething
,需要一些更多的代碼(尋找enable_if
,如果你想知道的)。
請注意,這種代碼(看你有什麼類型)是相當避免。你應該用虛擬功能來處理這些事情。向控制添加功能doSomething
,並在按鈕中覆蓋它。
一般情況下,C++的方式來寫一個列表執行算法, 序列, ...是提供迭代器作爲參數。
template < class iterator >
doSomething(iterator beg, iterator end);
這解決了列表按鈕< *>不從列表衍生<控制*>。 (使用模板列表< T *>也會,但這是讓你的函數通用 - 但不是真的)
根據我的經驗,在迭代器上操作良好的模板化函數可能會很多(太多...)的工作,但它是「C++的方式」...
如果你走這條路線,考慮使用Boost.ConceptCheck。它會讓你的生活變得更輕鬆。
好的,我的壞。我有指針列表,而不是對象列表。當然,將我的Button * s存儲在Control *列表中可以修復函數調用問題,而且我通常會這樣做,除非我想要一個Button *列表將它們用作Button,而不是Control。 – ggambett 2008-11-24 20:08:13
現在,你有什麼?列表
如果你只有一個列表,並且想要特殊情況下單個元素,如果它們是按鈕類型的,你將被迫使用dynamic_cast mate。 –
2008-11-24 20:23:18