【发布时间】:2019-12-20 08:21:35
【问题描述】:
当我们的团队处理关于 C++ 代码中 POD 的单元化成员的 valgrind 警告时,我得到了这个有趣的答案:
https://stackoverflow.com/a/5914697/629530
重申要点,考虑以下 C++ 中的 POD 结构:
struct C
{
int x;
int y;
};
以下构造 C 类型对象的调用会调用默认构造函数,并使用该默认构造函数初始化成员(同样,从 Martin York 的答案中复制代码和 cmets):
C c = C(); // Zero initialize using default constructor
C c{}; // Latest versions accept this syntax.
C* c = new C(); // Zero initialize a dynamically allocated object.
有道理。 Martin York 继续指出,在以下声明中,c 的成员不是通过构造函数初始化的,因此包含未定义的数据:
C c; // members are random
C* c = new C; // members are random (more officially undefined).
这很有趣。我之前使用过 braced-init-list 初始化 POD 类型,但我没有意识到 C c; 不会调用 POD 类型的默认构造函数。他的回答满足了这个问题,但我想知道在声明后者的非默认构造的 c 对象时具体实例化了什么。具体来说,以下内容对我有帮助:
- 这种 POD 类型的非默认初始化的正式名称是什么?由于我不知道它的名称,我无法在谷歌上搜索该机制。
- 如果 POD 类型有一些比 int 类型更重要的东西,例如 std::string,那么该成员的内存是否也用未定义的值初始化?或者是为该成员调用的 std::string 的默认构造函数?
更新。
感谢您的意见。这已被复制到一个带有这个单一答案的问题: https://stackoverflow.com/a/8860787/629530
根据该答案(以及它所复制到的问题的答案),不带括号的表单声明称为“默认初始化”:
Info *p = new Info; <------- Default Initialization
对于默认初始化,关于初始化的几点说明:
默认初始化 T 类型的对象意味着:
- 如果 T 是非 POD 类类型(第 9 条),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化格式错误);
- 如果 T 是数组类型,则每个元素都是默认初始化的;
- 否则,对象被零初始化。
我可能误解了一些东西,但上面提出的名为 C 的结构是 POD 类型,而不是数组。因此它应该是零初始化的?然而,成员不是零初始化的,而是包含未定义的值。我该如何调和呢?
【问题讨论】:
-
问题 1. 您是否正在寻找
value initialization?问题 2 应该单独提出,没有这么多的序言(并立即作为副本的副本关闭)
标签: c++