C ++模板和继承

时间:2008-11-24 19:49:16

标签: c++ inheritance templates

我的C ++框架有按钮。 Button来自Control。因此,接受Control的函数可以将Button作为其参数。到目前为止一切都很好。

我还有列表< T&gt;。但是,列表<按钮&gt;不是从List < Control&gt;派生的,这意味着接受控件列表的函数不能将Buttons列表作为其参数。这很不幸。

也许这是一个愚蠢的问题,但我不知道如何解决这个问题:(列表<按钮>应来自列表<控件> ,但我没有看到“自动”实现这一目标的方法。

5 个答案:

答案 0 :(得分:7)

Stroustrup在他的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

        }

    }
};

要仅为doSomething限制List<derived from Control>,还需要更多代码(如果您想了解,请查找enable_if)。

请注意,这种代码(看你有什么类型)是要避免的。你应该用虚函数来处理这些事情。将一个函数doSomething添加到Control,并在Button中覆盖它。

答案 1 :(得分:6)

如何使用指针?只需要一个list<Control*>列表,并将您喜欢的任何Control派生对象放入其中。

答案 2 :(得分:6)

我不想告诉你,但是如果你使用Control实例列表而不是指向Control的指针,你的按钮无论如何都会是垃圾(Google“对象切片”)。如果它们是指针列表,那么要么像其他人建议的那样将list<button*>变为list<control*>,要么从list<control*>复制到新的list<button*>并传递< em>那代替了。或者将该功能重写为模板。

因此,如果您之前有一个名为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 );
}

答案 3 :(得分:2)

使用List&lt; Control *&gt;而不是使用List&lt; Button&gt;,它们指向Buttons。这样,您的函数只需要采用一种类型:List&lt; Control *&gt;。

答案 4 :(得分:0)

通常,编写在列表,序列......上执行的算法的C ++方法是将迭代器作为参数提供。

template < class iterator >
doSomething(iterator beg, iterator end);

这解决了List&lt;按钮*&gt;不是从List&lt;控制*&gt;。 (使用模板List&lt; T *&gt;也会,但这会使你的函数变得通用 - 但不是真的)

根据我的经验,在迭代器上运行良好的模板化函数可能会有很多(太多......)工作,但它是“C ++方式”......

如果你走这条路,请考虑使用Boost.ConceptCheck。它会让你的生活更轻松。