在您开始将其标记为重复之前,我已阅读this 但它没有回答我的问题。链接的问题谈到了C ++ 98& C ++ 03但我的问题是关于C ++ 11引入的默认构造函数。
考虑以下计划(参见实时演示here):
#include <iostream>
struct Test
{
int s;
float m;
Test(int a,float b) : s(a),m(b)
{ }
Test()=default;
}t;
int main()
{
std::cout<<t.s<<'\n';
std::cout<<t.m<<'\n';
}
我的问题是,编译器提供的默认构造函数总是将内置类型初始化为默认值为0的C ++ 11&amp; C ++ 14当它们是class
&amp; struct
个成员。这种行为是否由C ++ 11标准保证?
答案 0 :(得分:14)
这个问题内置了两个不同的问题。
= default
对默认构造函数意味着什么?来自[class.ctor]:
默认构造函数是默认的,默认构造函数是默认构造函数,默认构造函数是默认使用的 (3.2)创建其类类型(1.8)的对象,或者在第一次声明后明确默认的对象。隐式定义的默认构造函数执行该类的初始化集合 由该类的用户编写的默认构造函数执行,没有ctor-initializer(12.6.2)和空 化合物语句。
也就是说,Test() = default
完全等同于Test() { }
,它会默认初始化s
和m
,这会将它们设置为某个不确定的值。
t.s
和t.m
如何初始化?是的,这是(1)中的一个单独问题,因为我们不只是在这里调用默认构造函数。来自[basic.stc.static]:
所有没有动态存储持续时间的变量,没有线程存储持续时间,并且是 非本地有静态存储时间。
和[basic.start.init]:
具有静态存储持续时间(3.7.1)或线程存储持续时间(3.7.2)的变量应为零初始化(8.5) 在进行任何其他初始化之前。
因此,t.s
和t.m
保证为0,即使我们默认构建了本地Test
,它们也不会。
答案 1 :(得分:8)
Test = default
将默认初始化其成员。
但对于int
或float
类型,默认初始化与值初始化
所以
Test t; // t.s and t.m have unitialized value
,而
Test t{}; // t.s == 0 and t.m == 0.0f;
答案 2 :(得分:5)
正如已经回答的那样,无法保证默认构造函数会“将内置类型自动初始化为0”。
您可以使用展示位置来自行查看。请考虑以下代码:
#include <iostream>
struct Test
{
int s;
float m;
Test(int a,float b) : s(a),m(b)
{ }
Test()=default;
};
int main()
{
char* buf = new char[sizeof(Test)];
Test* t = new (buf) Test;
std::cout << t->s << '\n';
std::cout << t->m <<'\n';
t->s = 42;
t->m = 4.2;
t->~Test();
t = new (buf) Test;
std::cout << t->s << '\n';
std::cout << t->m <<'\n';
}
如果保证默认构造函数对非类类型的数据成员进行零初始化,则该程序的输出将为四个零。
但是,您可能会看到类似的内容:
0
0
42
4.2
以下是cpp.sh上的代码 - http://cpp.sh/9fdj
答案 3 :(得分:3)
不,默认构造函数不做任何事情! 要初始化成员变量,您可以写:
struct Test
{
int s = 0;
float m = 3.3;
Test(int a,float b) : s(a),m(b)
{ }
Test()=default;
};
看看这个:C++ ctor = default
答案 4 :(得分:2)
出于所有目的:
Test() = default;
相当于:
Test() {}
因此它不会初始化内置类型的成员。