std :: vector元素的破坏顺序

sho*_*osh 21 c++ destructor vector

可能重复:
STL容器元素销毁顺序

是否有保证std::vector从最后到第一个被摧毁的元素?

Lig*_*ica 18

2003:5.3.5/6说delete[]:

delete-expression将调用对象的析构函数(如果有)或要删除的数组的元素.在数组的情况下,元素将按地址递减的顺序销毁(即,与构造函数完成的顺序相反;见12.6.2).

因此,如果你的std::vector对象的分配器使用delete[]那么,是的,它必然会以相反的顺序销毁元素.

但是,无法保证您的std::vector意愿以这种方式工作(事实上,它很可能没有),而且我找不到任何特定于容器的引用.

真的,我认为这完全取决于你的分配器和2003:20.1.5(列出对分配器的要求)似乎没有任何关于它的说法.

  • 几乎可以肯定`std :: vector`不会使用`delete []`,因为合理的实现需要额外分配但未初始化的空间,构造函数没有运行(因此析构函数不应该运行). (6认同)
  • @Tomalek:它使用`allocator_traits <allocator_type> :: construct`和`allocator_traits <allocator_type> :: destroy`,它们默认分别是放置新的和显式析构函数调用的包装器. (3认同)
  • @BenVoigt:我认为它使用了很多新的位置? (2认同)
  • @Tomalak:不仅不能保证向量在包含其元素的T数组上调用`delete []`,实际上它保证它*不会*(实际上)这样做.你无法一次实现一个"删除[]整个批次的分配器类,因为向量需要一次"破坏"它们.get-out子句是"as-if"规则 - 如果向量使用默认分配器,那么它*可能*`delete []`我想,但它必须作为特殊情况取决于该实例的历史,因为`vector :: resize()`仍然必须以某种方式实现. (2认同)

Ben*_*igt 5

他们标准保证原始数组的这一点,但我找不到任何可以保证容器的东西。

来自[expr.delete](C++0x 的新措辞):

如果 delete-expression 的操作数的值不是空指针值,则 delete-expression 将为要删除的对象或数组元素调用析构函数(如果有)。在数组的情况下,元素将按照地址递减的顺序销毁(即,按照其构造函数完成的相反顺序;参见 12.6.2)。

std::vector(事实上​​,标准库中的所有容器,可能不包括std::array)不用于delete[]销毁元素(它们allocator_traits<allocator_type>::destroy单独用于每个元素),因此上述保证不适用。std::vector对于删除顺序,我发现没有特别或一般容器的限制。对于某些容器,这样的保证会非常昂贵(例如std::forward_list,不能反向迭代元素以删除它们,并且std::map不记得添加对的顺序)。

来自[container.requirements.general](C++0x 措辞):

对于受本条影响的声明 allocator_type 的组件,存储在这些组件中的对象应使用 allocator_traits::construct 函数构造并使用 allocator_traits::destroy 函数(20.6.8.2)销毁。


Bo *_*son 5

不,对于数组,这里的所有元素都是按顺序构造并按相反顺序销毁的,这是有保证的。这与全局对象的处理方式有些一致。

另一方面,容器成员可以使用例如inserterase成员函数以任何顺序构造和销毁。为了保持一致并以相反的顺序破坏元素,这将要求容器在这些更改上保留某种日志。显然,这将是昂贵的!

最好的选择是容器析构函数调用clear(),其定义为erase(begin(), end()),但是我也找不到任何要求。该标准在表65中仅表示“线性复杂度”。

  • 我不知道为什么要对此予以否决,因为怯anonymous的匿名拒绝投票者未能发表评论。向我+1 (3认同)