C++模板和继承

问题描述:

我的C++框架有按钮。一个Button派生自Control。所以接受Control的函数可以将Button作为参数。到现在为止还挺好。C++模板和继承

我也有名单< T>。但是,列表<按钮>并非从List < Control>派生,这意味着接受控件列表的函数不能将Button列表作为其参数。这很不幸。

也许这是一个愚蠢的问题,但我不知道怎样才能解决这个:(名单<按钮>应该从列表<控制>得出,但我不明白的方式来做到这一点“自动”

+0

好的,我的坏。我有指针列表,而不是对象列表。当然,将我的Button * s存储在Control *列表中可以修复函数调用问题,而且我通常会这样做,除非我想要一个Button *列表将它们用作Button,而不是Control。 – ggambett 2008-11-24 20:08:13

+0

现在,你有什么?列表

+0

如果你只有一个列表,并且想要特殊情况下单个元素,如果它们是按钮类型的,你将*使用dynamic_cast mate。 – 2008-11-24 20:23:18

我不想告诉你,但是如果你正在使用实例列表来控制,而不是指向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。它会让你的生活变得更轻松。