【发布时间】:2017-11-03 13:28:11
【问题描述】:
通过值初始化的规则。值初始化发生:
1,5) 当使用初始化器创建无名临时对象时 由一对空的括号或大括号组成(C++11 起);
2,6) 当具有动态存储持续时间的对象由 new-expression 的初始化器由一对空的 圆括号或大括号 (C++11 起);
3,7) 当一个非静态数据 成员或基类使用成员初始化器初始化 一对空的括号或大括号 (C++11 起);
4) 当一个命名的 变量(自动、静态或线程局部)用 由一对大括号组成的初始化器。
简单的例子
struct A{
int i;
string s;
A(){};
};
A a{}
cout << a.i << endl // default initialized value
没有显式声明的构造函数并留下默认的默认ctor //编译器生成我们得到的一个。
struct A{
int i;
string s;
};
A a{};
cout << a.i << endl // zero-initialized value
但是使用另一个结构。
struct A{
int i;
string s;
};
struct B{
A a;
int c;
};
B a{};
cout << a.a.i << endl // default initialized , even tho we did not , int struct B , declared A a{}.
a.i 的值是零初始化的,即使没有使用 {} / () 构造,这违反了规则(如果我没记错的话)。
在结构 B 上使用相同的逻辑:
struct A{
int i;
string s;
};
struct B{
A a;
int c;
};
B b;
cout << b.c << endl; // default inicialized
我们根据规则获得行为。
最后一个例子:
struct A
{
int i;
A() { }
};
struct B { A a; };
std::cout << B().a.i << endl;
B().a.i 也是零初始化的,而我们显式声明了构造函数并且它没有被删除。
为什么这些值被初始化为零?根据here 规定的规则,它们应该是默认初始化而不是零初始化。
感谢您的回答。
【问题讨论】:
-
最后一个例子来自 cppreference (link)。并且它声明了它的零初始化。
-
我在最初的评论中很快就谈到了。在访问
a.i的第一个示例中是UB。第二个是聚合初始化,所以没关系。第三个也是聚合初始化,这样就可以了。在第四个例子中访问b.c是UB。在第五个示例中,访问a.i是可以的,因为您引用的第一条规则。
标签: c++ c++11 value-initialization