成员初始化
优先初始化器列表,其次默认初始化器,最后默认初始化(对于原始类型就是未初始化)
构造函数体在初始化器列表之后执行
如果没有任何用户声明的构造函数,会生成默认构造函数,它可以被视作是无参数,无初始化器列表,体内为空。但生成的默认构造函数和手动编写的空构造函数仍然有细微区别:
- C++20之前explicit默认构造函数不会使得类变成non-aggregate,C++20之后会了
int a; // no initializer (default initialization)
int b = 5; // initializer after equals sign (copy initialization)
int c( 6 ); // initializer in parentheses (direct initialization)
// List initialization methods (C++11)
int d { 7 }; // initializer in braces (direct list initialization)
int e = { 8 }; // initializer in braces after equals sign (copy list initialization)
int f {}; // initializer is empty braces (value initialization)
// Calls Foo() default constructor
Foo f1; // default initialization
Foo f2{}; // value initialization (preferred)
// Calls foo(int) normal constructor
Foo f3 = 3; // copy initialization (non-explicit constructors only)
Foo f4(4); // direct initialization
Foo f5{ 5 }; // direct list initialization (preferred)
Foo f6 = { 6 }; // copy list initialization (non-explicit constructors only)
// Calls foo(const Foo&) copy constructor
Foo f7 = f3; // copy initialization
Foo f8(f3); // direct initialization
Foo f9{ f3 }; // direct list initialization (preferred)
Foo f10 = { f3 }; // copy list initializationThere are three key differences between the initialization forms:
- List initialization disallows narrowing conversions.
- Copy initialization only considers non-explicit constructors/conversion functions.
- List initialization prioritizes matching list constructors over other matching constructors.
copy elision
as-if豁免,故复制构造函数不应当有副作用
Only one user-defined conversion may be applied
printEmployee("Joe"); // we're supplying an string literal argument其中该函数接受Employee对象,Employee对象只能通过stringview初始化,该代码无法编译通过