是否保证默认构造函数将内置类型自动初始化为 0?
Is it guaranteed that defaulted constructor initialize built in types automatically to 0?
在你开始将其标记为重复之前,我已经阅读过 this
.但它没有回答我的问题。链接的问题讨论的是 C++98 和 C++03,但我的问题是关于 C++11 引入的 defaulted constructor。
考虑以下程序(查看现场演示 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';
}
我的问题是编译器在这里提供的默认构造函数总是在 C++11 和 C++14 中将内置类型默认初始化为 0,当它们是 class
和 struct
时成员。 C++11 标准保证这种行为吗?
出于所有目的:
Test() = default;
相当于:
Test() {}
因此它不会初始化内置类型的成员。
不,默认构造函数什么都不做!
要初始化成员变量,您可以这样写:
struct Test
{
int s = 0;
float m = 3.3;
Test(int a,float b) : s(a),m(b)
{ }
Test()=default;
};
看看这个:C++ ctor = default
这个问题内置了两个单独的问题。
默认构造函数的= default
是什么意思?来自 [class.ctor]:
A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used
(3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be
performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty
compound-statement.
也就是说,Test() = default
完全等同于 Test() { }
,它将默认初始化 s
和 m
,将它们设置为某个不确定的值。
t.s
和t.m
是如何初始化的?是的,这是与 (1) 不同的问题,因为我们不只是在这里调用默认构造函数。来自 [basic.stc.static]:
All variables which do not have dynamic storage duration, do not have thread storage duration, and are
not local have static storage duration.
来自[basic.start.init]:
Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5)
before any other initialization takes place.
因此 t.s
和 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;
因为已经回答了,所以不能保证默认构造函数会 "initialize built in types automatically to 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';
}
如果保证默认构造函数对非class类型的数据成员进行零初始化,则该程序的输出将是四个零。
但是,您可能会看到类似这样的内容:
0
0
42
4.2
这是 cpp.sh - http://cpp.sh/9fdj
上的代码
在你开始将其标记为重复之前,我已经阅读过 this .但它没有回答我的问题。链接的问题讨论的是 C++98 和 C++03,但我的问题是关于 C++11 引入的 defaulted constructor。
考虑以下程序(查看现场演示 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';
}
我的问题是编译器在这里提供的默认构造函数总是在 C++11 和 C++14 中将内置类型默认初始化为 0,当它们是 class
和 struct
时成员。 C++11 标准保证这种行为吗?
出于所有目的:
Test() = default;
相当于:
Test() {}
因此它不会初始化内置类型的成员。
不,默认构造函数什么都不做! 要初始化成员变量,您可以这样写:
struct Test
{
int s = 0;
float m = 3.3;
Test(int a,float b) : s(a),m(b)
{ }
Test()=default;
};
看看这个:C++ ctor = default
这个问题内置了两个单独的问题。
默认构造函数的
= default
是什么意思?来自 [class.ctor]:A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr-used (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration. The implicitly-defined default constructor performs the set of initializations of the class that would be performed by a user-written default constructor for that class with no ctor-initializer (12.6.2) and an empty compound-statement.
也就是说,
Test() = default
完全等同于Test() { }
,它将默认初始化s
和m
,将它们设置为某个不确定的值。t.s
和t.m
是如何初始化的?是的,这是与 (1) 不同的问题,因为我们不只是在这里调用默认构造函数。来自 [basic.stc.static]:All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration.
来自[basic.start.init]:
Variables with static storage duration (3.7.1) or thread storage duration (3.7.2) shall be zero-initialized (8.5) before any other initialization takes place.
因此
t.s
和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;
因为已经回答了,所以不能保证默认构造函数会 "initialize built in types automatically to 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';
}
如果保证默认构造函数对非class类型的数据成员进行零初始化,则该程序的输出将是四个零。
但是,您可能会看到类似这样的内容:
0
0
42
4.2
这是 cpp.sh - http://cpp.sh/9fdj
上的代码