[英]Default initialization of class data members in C++11
I'm confused about the default initialization of the class data members.我对类数据成员的默认初始化感到困惑。 Here is the sample code.
这是示例代码。
#include <iostream>
#include <vector>
class A {
public:
int i;
A() {}
};
A a1;
A aa1[3];
std::vector<A> av1(3);
int main()
{
A a2;
A aa2[3];
std::vector<A> av2(3);
std::cout << a1.i << " " << a2.i << std::endl; // 0 undefined
std::cout << aa1[0].i << " " << aa2[0].i << std::endl; // 0 undefined
std::cout << av1[0].i << " " << av2[0].i << std::endl; // undefined undefined
}
In the code above, only a1.i
and aa1[0~2].i
are initialized to 0, while others are uninitialized.上面的代码中只有
a1.i
和aa1[0~2].i
被初始化为0,其他的都没有初始化。 I don't know why is that happened.我不知道为什么会这样。
To be specifically, what I already know is that (From "C++ Primer"):具体来说,我已经知道的是(来自“C++ Primer”):
The process of initialization is:初始化过程为:
a1
and a2
are default initialized . a1
和a2
是默认初始化的。aa1
and aa2
are default initialized . aa1
和aa2
的每个元素都是默认初始化的。av1
and av2
are value initialized . av1
和av2
的每个元素都是值初始化的。 The process of default initialize is:默认初始化的过程是:
The process of value initialize is:值初始化的过程是:
So that when the ctor A::A()
is called, how the data member A::i
initialized (I guess it is default initialized)?那么当调用构造函数
A::A()
时,数据成员A::i
是如何初始化的(我猜它是默认初始化的)? And why only a1.i
and aa1[0~2].i
are initialized to 0, while others are uninitialized?还有为什么只有
a1.i
和aa1[0~2].i
初始化为0,其他的都没有初始化?
when the ctor A::A() is called, how the data member A::i initialized
当构造函数 A::A() 被调用时,数据成员 A::i 是如何初始化的
If no initializer is provided, the rules of default initialization apply.如果未提供初始化器,则应用默认初始化规则。 Your constructor does no initialization of
A::i
so it's left uninitialized;你的构造函数没有初始化
A::i
所以它没有被初始化; it's value is indeterminate.它的价值是不确定的。 No doubt about that.
毫无疑问。 Excerpt from the documentation on default initialization :
摘自关于默认初始化的文档:
If T is a class type, the constructors are considered and subjected to overload resolution against the empty argument list.
如果 T 是类类型,则考虑构造函数并对空参数列表进行重载解析。 The constructor selected (which is one of the default constructors) is called to provide the initial value for the new object.
选择的构造函数(默认构造函数之一)被调用以提供新对象的初始值。
why only a1.i and aa1[0~2].i are initialized to 0, while others are uninitialized?
为什么只有a1.i和aa1[0~2].i被初始化为0,其他的都没有初始化?
The global data memory is initialized to zero ie the whole section is zeroed out and so you see global A::i
s initialized to 0
.全局数据内存被初始化为零,即整个部分被清零,所以你看到全局
A::i
被初始化为0
。 Note that the constructor would not be doing this.请注意,构造函数不会这样做。 Excerpt from the documentation :
文档摘录:
Static initialization
静态初始化
[...]
[...]
2) For all other non-local static and thread-local variables, Zero initialization takes place.
2) 对于所有其他非本地静态和线程本地变量, 零初始化发生。 In practice, variables that are going to be zero-initialized are placed in the.bss segment of the program image, which occupies no space on disk, and is zeroed out by the OS when loading the program.
在实践中,将被零初始化的变量放在程序映像的.bss 段中,该段不占用磁盘空间,并在加载程序时由操作系统清零。
However, for the vector
, the vector
itself is in the non-local static memory while its elements are allocated in free store (heap) and hence their members are uninitialized too.但是,对于
vector
, vector
本身位于非本地静态内存中,而其元素分配在自由存储(堆)中,因此它们的成员也未初始化。
Global (both static and exported) variables are zero-initialized (in practice, on usual platforms, they are in memory are which is filled with zeros at program start), if they are not explicitly initialized and don't have a constructor.全局(静态和导出)变量是零初始化的(实际上,在通常的平台上,它们在内存中,在程序启动时用零填充),如果它们没有显式初始化并且没有构造函数。
Items of vector are default-initialized, when you use the constructor you are using in your code.当您使用您在代码中使用的构造函数时,向量项是默认初始化的。
For a vector class object, both mean a constructor call.对于向量类对象,两者都意味着构造函数调用。 But for integers, first means initialized to zero, while latter means initialized with indeterminate value.
但对于整数,first 表示初始化为零,而 latter 表示初始化为不确定值。 So the plain int variables in your code are zero-initialized, but the ints in the vector are default initialized.
所以代码中的普通 int 变量是零初始化的,但向量中的 int 是默认初始化的。
Some links for reference:一些链接供参考:
You declare a constructor for A
, so there is no default initialization of i
;您为
A
声明了一个构造函数,因此没有i
的默认初始化; that's your responsibility in the constructor.这是你在构造函数中的责任。 The global variables get initial values of 0 because they're global.
全局变量的初始值为 0,因为它们是全局的。 All globals are initialized to 0 if they aren't given an initial value by some means.
如果未通过某种方式为所有全局变量赋予初始值,则所有全局变量都将初始化为 0。
The local variables and vectors get random data because that's what's in the memory on the stack (for locals) or heap (for the allocated memory that the vector uses) that is being used by those A
instances.局部变量和向量获取随机数据,因为这是那些
A
实例正在使用的堆栈(对于局部变量)或堆(对于向量使用的分配内存)中的内存。
The initialization of an object of class type is controlled by the class, and this process is done recursively .类类型对象的初始化由类控制,这个过程是递归完成的。 Take your sample code for example, the initialization of
i
is controlled by A
.以您的示例代码为例,
i
的初始化由A
控制。 Since no constructor is provided, the synthesized default constructor will be used.由于未提供构造函数,因此将使用合成的默认构造函数。 And since no in-class initializers are provided, every member of
A
is default initialized, again, the default initialization rule is queried.并且由于没有提供类内初始化器,所以
A
的每个成员都被默认初始化,同样,默认初始化规则被查询。 The built-in type i
will be left uninitialized.内置类型
i
将保持未初始化状态。 If A
contains a member s
of type string
, then the default initialization of s
is controlled by the string
class ( the recursive rule takes place ).如果
A
包含类型为string
的成员s
,则s
的默认初始化由string
类控制(递归规则发生)。 In this case, s
will be initialized to an empty string.在这种情况下,
s
将被初始化为一个空字符串。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.