可以/我应该从STL迭代器继承吗?

时间:2011-06-24 16:45:07

标签: c++ stl iterator

可以/我应该从STL迭代器继承来实现我自己的迭代器类吗?如果不是,为什么不呢?

3 个答案:

答案 0 :(得分:8)

如果你的意思是std::iterator:是的,那就是它的用途。

如果你的意思是:no,因为没有STL迭代器有virtual个析构函数。它们不是为了继承,而从它们继承的类可能无法正常清理。

答案 1 :(得分:5)

如果你在谈论std::iterator模板,那么你应该,但我希望你明白它没有任何功能,只是一堆typedef。这个决定的优点是你的迭代器可以被送到iterator_traits模板。

另一方面,如果您正在谈论某些特定的STL迭代器,如vector<T>::iterator或其他,那么答案就是响亮的 NO 。更不用说其他一切了,你不确定它实际上是一个类(例如同一个vector<T>::iterator可以只是被定义为T*

答案 2 :(得分:5)

由于可能遇到的潜在问题,没有人不应该这样做。可能最好使用 组合 而不是 继承 与STL迭代器。

由于缺少虚拟析构函数而导致未定义的行为:
STL容器&amp;迭代器并不意味着充当基类,因为它们没有虚拟析构函数。

对于没有将虚拟析构函数用作Base类的类,在通过指向基类的指针(delete,delete []等)解除分配时会出现问题。由于类没有虚拟析构函数,因此无法正确清理它们并导致未定义的行为。

有人可能会争辩说,不需要以多态方式删除迭代器。因此从STL迭代器派生出来并没有错,可能还有其他一些问题,如:

可能根本无法继承:
标准容器中的所有迭代器类型都是 实现已定义 例如:std::vector<T>::iterator可能只是T*。在这种情况下,您根本无法继承它。

C ++标准没有要求说std::vector<T>::iterator没有 使用继承抑制技术来防止派生。因此,如果从STL迭代器派生,则依赖于STL的一个特性,该特性恰好允许派生。这使得这种实现 非便携式

如果没有正确实施,则会出现多种行为:
考虑您从vector迭代器类派生,如:

class yourIterator : std::vector<T>::iterator { ... };

可能有一个函数在向量迭代器上运行,
例如:

void doSomething(std::vector<T>::iterator to, std::vector<T>::iterator from);

由于yourIteratorstd::vector<T>::iterator,您可以在容器类上调用doSomething(),但是您将面临Object Slicing的丑陋问题。 doSomething()必须以适当的模板方式实现,以避免。{1}} 问题

使用标准库算法时遇到的问题:
考虑您正在使用矢量迭代器的派生,然后使用标准库算法,如std::transform()

对于Ex:

yourIterator a;
yourIterator b;
...
std::transform( a++, b--, ... );

后缀operator ++返回std::vector<T>::iterator而不是a yourIterator导致选择了错误的模板。

因此,继承STL迭代器确实是可能的,但如果你准备好挖掘所有这些和许多其他潜在的问题并解决它们,我个人不会给它时间和努力。