没有使用大括号的情况下,POD成员的默认初始化

6

给定代码:

struct Test {
    int a = 1;
    int b = 2;
};

Test test1;
Test test2{};

对于 test2 ,我确定 test2.a == 1test2.b == 2。那么对于没有 {}test1 ,这个是否保证相同?


2
是的,这是有保证的。你为什么会认为它不是呢? - YePhIcK
@YePhIcK,我有些疑惑。你能指向一下标准吗? - vladon
除非在11和14之间有所改变,否则我不明白为什么test1不会被设置为12 - YePhIcK
3
这不是一个 POD。 - T.C.
3个回答

7
该行
Test test1;

等同于使用默认构造函数进行初始化,如果没有手动编写一个显示的初始化列表且没有将 Test() = deleted;,那么会将两个成员变量设置为它们指定的初始值 12

“默认构造函数”是一种可以无需参数调用的构造函数,这恰好符合上述语句的情况。

您可以在标准文件中查阅有关默认构造函数的规则 - 转至§ 12.1第4节:

类X的默认构造函数是可以在没有参数的情况下调用的X类的构造函数...

并在第5节进一步说明:

当需要创建其类类型(1.8)的对象时使用默认值并未定义为删除的默认构造函数将自动定义为默认,即使未显式地声明该函数也是如此(3.2)...


6

是的,在这里它们有相同的效果。

对于第一种情况,它是使用默认初始化

如果T是类类型,则考虑构造函数并针对空参数列表进行重载解析。选择的构造函数(其中之一是默认构造函数)被调用以为新对象提供初始值;

这意味着将调用隐式定义的默认构造函数; 它不使用任何成员初始化列表,然后默认成员初始化程序会生效来初始化数据成员。

对于第二种情况,它是聚合初始化

如果初始化程序子句的数量小于成员和基类(自C++17以来)的数量,或初始化程序列表完全为空,则其余成员和基类(自C++17以来)通过其默认初始化程序进行初始化,如果在类定义中提供了该初始化程序,则会使用它们,否则(自C++14以来)...

因此, 默认成员初始化程序也会生效来初始化数据成员。


@hvd 你的意思是在C++14之前吗?(是的,在C++14之前它变成了值初始化;而Test不是一个聚合类型。) - songyuanyao
我搞糊涂了,抱歉。你是对的。我混淆了哪些内容被包含在C++14中,哪些没有。 - user743382

4

test1也保证其成员a被初始化为1,其成员b被初始化为2

引自C++11 FAQ, 类内成员初始化

The basic idea for C++11 is to allow a non-static data member to be initialized where it is declared (in its class). A constructor can then use the initializer when run-time initialization is needed. Consider:

class A {
  public:
    int a = 7;
};

This is equivalent to:

class A {
  public:
    int a;
    A() : a(7) {}
};

这对我来说看起来是正确的陈述。我很好奇为什么会被投票否决?两次! - YePhIcK
3
@YePhIcK,我之前的回答错误了。我在没有清楚阅读问题的情况下发布了一个答案。 - R Sahu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接