初始化(Initialization)
初始化是指变量在创建的同时获得的初始值。虽然C++经常用=
来初始化一个变量,但是赋值和初始化是两种不同的操作。赋值是变量定义后的操作,效果是改变变量的值,或者说是用新值来替换旧值;而初始化是在变量创建期获得一个值。两者具有本质的区别。下面分别介绍一下C++常见的初始化方式:
default initialization
当我们定义一个变量时,不提供initializer,那么这个变量就是默认初始化(default initialized)的。默认值由变量的类型和变量的定义位置来决定。
- 对于built-in type,默认值由变量的定义位置决定。在函数外部定义的全局变量(global variable),函数内部定义的局部静态变量(local static object)全部初始化为0。函数内部定义的局部变量,以及类中不在初始化成员列表和构造函数里体的成员变量都是未初始化的;使用未初始化的变量值的行为是未定义的,编译器不保证不会自燃。
- 对于class type,由类里的默认构造函数初始化。如果类定义里没有默认构造函数(显示或隐示),则编译出错。
list initialization
C++11中提供了一种新的初始化方式,list initialization,以大括号包围。A tour of c++中写到The = form is traditional and dates back to C, but if in doubt, use the general {}-list form
。注意这种初始化方式要求提供的初始值与要初始化的变量类型严格统一,用法如下,
//built-in type initialization
double d1{2.3}; //ok: direct-list-initialization
double d2 = {2.3}; //ok: copy-list-initialization
//class type initialization
complex<double> z2 {d1,d2};
complex<double> z3 = {1,2}; //ok: the = is optional with {...}
vector<int> v {1,2,3,4,5,6}; //ok: a vector of ints
long double pi = 3.1415;
int a{pi}, b = {pi}; //error: narrowing conversion required.
int c(pi), d = pi; //ok: implict conversion.
value initialization
value initialization里,built-in type变量被初始化为0,class type的对象被默认构造(一定要有)初始化。这种方式通常见于STL里的vector和数组,且经常与list initialization结合起来使用,为我们初始化全0数组提供了很大的便利。简单用法如下:
vector<int> ivec(10); //ten elements, each initialized to 0
vector<string> svec(10); //ten elmenets, each an empty string
vector<string> v1 = {"a", "an", "the"}; //list initialized
int a[10] = {}; //ten elements, each initialized to 0
int a2[] = {1,2,3}; //list initialized
int a3[5] = {1,2,3}; //equivalent to a3[] = {1,2,3,0,0}