[英]C++ templates and inheritance
我的C ++框架有Buttons。 Button來自Control。 因此,接受Control的函數可以將Button作為其參數。 到現在為止還挺好。
我也有List <
T>。 但是,List <
Button>不是從List <
Control>派生的,這意味着接受控件列表的函數不能將Buttons列表作為其參數。 這很不幸。
也許這是一個愚蠢的問題,但我不知道如何解決這個問題:( List <
Button >
應該來自List <
Control >
,但我沒有看到一種方法來“自動”實現這一點。
Stroustrup在他的FAQ中有一個項目:
為什么我不能將vector<Apple*>
指定給vector<Fruit*>
您可以通過兩種方式解決它:
Control
指針。 然后接受List<Control*>
List<Button>
和List<Control>
,但它更多的是樣板代碼,而不是大多數時候的neopssary。 這是第二種替代方案的代碼。 第一種選擇已經由其他答案解釋:
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
to Control,並在Button中覆蓋它。
使用指針怎么樣? 只需要一個列表list<Control*>
,並將您喜歡的任何Control派生對象放入其中。
我不想告訴你,但是如果你使用Control實例列表而不是指向Control的指針,你的按鈕無論如何都會是垃圾(Google“對象切片”)。 如果他們是指針列表,然后可以使list<button*>
到list<control*>
正如其他人的建議,或做一個拷貝到一個新的list<control*>
從list<button*>
並傳遞進入功能而不是。 或者將該功能重寫為模板。
因此,如果您之前有一個名為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 <Button>,使用List <Control *>,它們指向Buttons。這樣,您的函數只需要采用一種類型:List <Control *>。
通常,編寫在列表,序列,...上執行的算法的C ++方法是提供迭代器作為參數。
template < class iterator >
doSomething(iterator beg, iterator end);
這解決了List <Button *>不是從List <Control *>派生的。 (使用模板List <T *>也會,但這會讓你的函數變得通用 - 但不是真的)
根據我的經驗,在迭代器上運行良好的模板化函數可能會有很多(太多......)工作,但它是“C ++方式”......
如果你走這條路,考慮使用Boost.ConceptCheck 。 它會讓你的生活更輕松。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.