关于本章
"initialization"即“初始化”,本章描述c++中initialization的概念、如何进行initialization等内容。
发展概述
C++98
C++03
弥补了Default initialization中,indeterminate value(中间值) undefined behavior。
C++11
1、List initialization (since C++11)
统一了syntax、消除了syntax ambiguity,进行了simplify。
区分
C++的initialization章节中,出现了非常多的initialization术语,如何对它们进行区分、记忆呢?
带参 与 不带参的initialization
不带参的initialization:
1、default initialization
2、value initialization
带参的initialization:
1、copy initialization
2、directed initialization
Default initialization VS value initialization
参见:
1、akrzemi1 Value-initialization with C++
遵循 CppCoreGuidelines ES.20: Always initialize an object,阅读完成后,我的一个想法是: 我们总是需要value initialization,C++11 的 uniform initialization {}
让我们以uniform、consistent syntax来实现 value initialization。
stackoverflow Do the parentheses after the type name make a difference with new?
NOTE:
1、非常能够体现 Default initialization VS value initialization
Let's get pedantic, because there are differences that can actually affect your code's behavior. Much of the following is taken from comments made to an "Old New Thing" article.
Sometimes the memory returned by the new operator will be initialized, and sometimes it won't depending on whether the type you're newing up is a POD (plain old data), or if it's a class that contains POD members and is using a compiler-generated default constructor.
- In C++1998 there are 2 types of initialization: zero and default
- In C++2003 a 3rd type of initialization, value initialization was added.
Assume:
struct A { int m; }; // POD
struct B { ~B(); int m; }; // non-POD, compiler generated default ctor
struct C { C() : m() {}; ~C(); int m; }; // non-POD, default-initialising m
In a C++98 compiler, the following should occur:
new A
- indeterminate valuenew A()
- zero-initializenew B
- default construct (B::m is uninitialized)new B()
- default construct (B::m is uninitialized)new C
- default construct (C::m is zero-initialized)new C()
- default construct (C::m is zero-initialized)
In a C++03 conformant compiler, things should work like so:
new A
- indeterminate valuenew A()
- value-initialize A, which is zero-initialization since it's a POD.new B
- default-initializes (leaves B::m uninitialized)new B()
- value-initializes B which zero-initializes all fields since its default ctor is compiler generated as opposed to user-defined.new C
- default-initializes C, which calls the default ctor.new C()
- value-initializes C, which calls the default ctor.
So in all versions of C++ there's a difference between new A
and new A()
because A is a POD.
And there's a difference in behavior between C++98 and C++03 for the case new B()
.
This is one of the dusty corners of C++ that can drive you crazy. When constructing an object, sometimes you want/need the parens, sometimes you absolutely cannot have them, and sometimes it doesn't matter.
Directed initialization 和 value initialization
directed initialization 和 value initialization 的syntax非常类似,区别在于directed initialization提供了参数。
Direct initialization 和 Copy initialization
cppreference Direct initialization
Direct-initialization is more permissive(自由、宽松) than copy-initialization:
copy-initialization only considers non-explicit constructors and non-explicit user-defined conversion functions, while
direct-initialization considers all constructors and all user-defined conversion functions.
如果只有explicit,那么是无法使用copy initialization的。
TODO
stackoverflow What do the following phrases mean in C++: zero-, default- and value-initialization?