簡體   English   中英

C ++模板和繼承

[英]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*>

您可以通過兩種方式解決它:

  • 使List包含指向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*> 傳遞進入功能而不是。 或者將該功能重寫為模板。

因此,如果您之前有一個名為doS​​omething的函數,它將控件列表作為參數,那么您將其重寫為:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM