【发布时间】:2013-02-15 13:06:24
【问题描述】:
假设我们使用std::vector<int> 或std::vector<long>。随着向量大小的增长,新分配的元素是默认初始化为0,还是程序员需要显式地将它们初始化为0?
【问题讨论】:
假设我们使用std::vector<int> 或std::vector<long>。随着向量大小的增长,新分配的元素是默认初始化为0,还是程序员需要显式地将它们初始化为0?
【问题讨论】:
新的元素是值初始化的:
[C++11: 23.3.6.3/9]:void resize(size_type sz);
效果:如果sz <= size(),则相当于erase(begin() + sz, end());。如果是size() < sz,则将sz - size()value-initialized 元素附加到序列中。
对于int 和long 这意味着0:
[C++11: 8.5/7]:对T类型的对象进行值初始化意味着:
- 如果
T是具有用户提供的构造函数 (12.1) 的(可能是 cv 限定的)类类型(第 9 条),则调用T的默认构造函数(并且如果T没有可访问的默认构造函数);- 如果
T是一个(可能是 cv 限定的)非联合类类型,没有用户提供的构造函数,则对象为零初始化,并且如果T的隐式声明的默认构造函数是非微不足道,调用该构造函数。- 如果
T是数组类型,那么每个元素都是值初始化的;- 否则,对象被零初始化。
值初始化的对象被认为是已构造的,因此受本国际标准适用于“构造的”对象、“构造函数已完成的对象”等的规定的约束,即使没有调用构造函数用于对象的初始化。
但请注意,这不是在谈论向量末尾的“保留”空间。该空间不包含任何有效元素,零-初始化或其他方式。此答案和标准措辞仅涉及您在执行 resize 时获得的元素,而没有为新元素指定显式值。
【讨论】:
根据 C++11 标准的第 23.3.6.3/9 段(关于 std::vector::resize()):
void resize(size_type sz);效果:如果sz value-initialized 元素附加到序列中。
此外,根据标准第 8.5/7 段:
值初始化一个 T 类型的对象意味着:
——如果 T 是一个(可能是 cv 限定的)类类型(第 9 条),带有一个用户提供的构造函数(12.1),那么 调用 T 的默认构造函数(如果 T 没有可访问的默认值,则初始化格式错误 构造函数);
——如果 T 是一个(可能是 cv 限定的)非联合类类型,没有用户提供的构造函数,那么对象 是零初始化的,如果 T 的隐式声明的默认构造函数是非平凡的,则该构造函数是 调用。
——如果T是一个数组类型,那么每个元素都是值初始化的;
— 否则,对象被零初始化。
这意味着在 int 的情况下,新创建的元素的值初始化为 0。
【讨论】:
是的,当std::vector 改变大小时(可能通过std::vector::resize),任何新元素都将被值初始化。对于 int 或 long 这样的类型,值初始化会导致零初始化,顾名思义,会将值设置为 0。
【讨论】: