【发布时间】:2011-09-04 09:02:25
【问题描述】:
【问题讨论】:
-
我想这取决于保证是否也适用于原始数组,因为 std::vector 确实模仿了数组。但我不知道标准对此有何规定。
-
@Klaim:
std::vector仅使用op[]语法模拟数组;这没有说明任何元素寿命保证。
标签: c++ vector destructor
【问题讨论】:
std::vector 仅使用 op[] 语法模拟数组;这没有说明任何元素寿命保证。
标签: c++ vector destructor
2003:5.3.5/6 说delete[]:
delete-expression 将为要删除的对象或数组的元素调用析构函数(如果有)。在数组的情况下,元素将被销毁按地址递减顺序(即,按其构造函数完成的相反顺序;参见 12.6.2)。
所以如果你的std::vector 对象的分配器使用delete[] 那么,是的,它必然会以相反的顺序销毁元素。
但是,不能保证您的 std::vector 会以这种方式工作(事实上,它很可能不会),而且我找不到任何特定于容器的引用。
真的,我认为这完全取决于您的分配器,而 2003:20.1.5(列出了对分配器的要求)似乎没有说明任何内容。
【讨论】:
std::vector 不会使用delete[],因为合理的实现需要额外分配但未初始化的空间,构造函数没有运行(因此析构函数不应该运行) .
allocator_traits<allocator_type>::construct 和allocator_traits<allocator_type>::destroy,默认情况下,它们分别是放置 new 和显式析构函数调用的包装器。
delete[],事实上它保证它不会 (实际上)这样做。您无法一次性实现delete[]s 的所有分配器类,因为需要destroy 一次一个的向量。 get-out 子句是“as-if”规则 - 如果向量使用默认分配器,那么它 可以 delete[] 我想,但它必须是一个特殊情况,具体取决于该实例的历史,因为vector::resize() 仍然需要以某种方式实现。
不,数组有有保证,其中所有元素的构造都是有序的,并以相反的顺序销毁。这与处理全局对象的方式有些一致。
另一方面,容器成员可以使用insert 和erase 成员函数以任何顺序构造和销毁。为了保持一定的一致性并以相反的构造顺序销毁元素,这将要求容器对这些更改保留某种日志。显然这会很贵!
最好的办法是容器析构函数调用clear(),它被定义为erase(begin(), end()),但我也找不到任何要求。该标准仅在表 65 中说明“线性复杂度”。
【讨论】:
他们标准为原始数组保证这一点,但我找不到任何可以保证容器的东西。
来自[expr.delete](C++0x 的新措辞):
如果删除表达式的操作数的值不是空指针值,删除表达式将 调用要删除的对象或数组元素的析构函数(如果有)。在一个 数组,元素将按地址递减的顺序销毁(即完成的相反顺序) 他们的构造函数;见 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) 销毁。
【讨论】: