在开始将其标记为重复之前,我已经阅读过。但这并不能回答我的问题。链接的问题谈到了C++98&C++03,但我的问题是关于C++11引入的默认构造函数。
考虑以下程序(请参阅此处的实时演示):
#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';
}
我的问题是,编译器提供的默认构造函数在C++11&当它们是CCD_ 1&struct
成员。C++11标准是否保证了这种行为?
这个问题中内置了两个独立的问题。
-
= default
对默认构造函数意味着什么?来自[class.ctor]:使用odr时,会隐式定义默认且未定义为已删除的默认构造函数(3.2)创建其类类型(1.8)的对象,或者当它在第一次声明后显式默认时。隐式定义的默认构造函数执行类的一组初始化由用户为该类编写的默认构造函数执行,该类没有ctor初始值设定项(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)在进行任何其他初始化之前。
因此,
class
0和t.m
被保证为0,即使我们默认构造本地Test
,它们也不会是。
Test = default
将默认初始化其成员。但对于int
或float
类型,默认初始化与值初始化不同
所以
Test t; // t.s and t.m have unitialized value
而
Test t{}; // t.s == 0 and t.m == 0.0f;
正如已经回答的那样,不能保证默认构造函数将"自动将内置类型初始化为0"。
您可以使用placement new亲自查看。考虑以下代码:
#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
不,默认构造函数什么都不做!要初始化成员变量,您可以编写:
struct Test
{
int s = 0;
float m = 3.3;
Test(int a,float b) : s(a),m(b)
{ }
Test()=default;
};
看看这个:C++ctor=默认
用于所有目的:
Test() = default;
相当于:
Test() {}
因此,它不会初始化内置类型的成员。