Des*_*tor 11 c++ initialization default-constructor language-lawyer c++11
在你开始将其标记为重复之前,我已经读过这个 .但它没有回答我的问题.链接的问题谈到了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';
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,编译器提供的默认构造函数总是初始化内置类型,在C++ 11和C++ 14中默认为0,当它们是class&struct成员时.这种行为是否由C++ 11标准保证?
Bar*_*rry 15
这个问题内置了两个不同的问题.
= default默认构造函数意味着什么?来自[class.ctor]:
当使用odr-used(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,它们也不会.
Test = default将默认初始化其成员.但对于类型为int或float,默认初始化与值初始化不同
所以
Test t; // t.s and t.m have unitialized value
Run Code Online (Sandbox Code Playgroud)
而
Test t{}; // t.s == 0 and t.m == 0.0f;
Run Code Online (Sandbox Code Playgroud)
由于已经回答,因此无法保证默认构造函数将"自动将内置类型初始化为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';
}
Run Code Online (Sandbox Code Playgroud)
如果保证默认构造函数对非类类型的数据成员进行零初始化,则此程序的输出将为四个零.
但是,您可能会看到类似的内容:
0
0
42
4.2
Run Code Online (Sandbox Code Playgroud)
这是cpp.sh上的这段代码 - http://cpp.sh/9fdj