注:该整理并不全面或准确,仅供参考,欢迎评论交流。本文部分内容来自 C++primer 中文版第五版 原文。
变量初始化有几种:
默认初始化:内置类型定义于函数体内其值未定义,定义于函数体外被初始化为0;类类型由默认构造函数初始化
值初始化:内置类型初始化为0;类类型由默认构造函数初始化
显示初始化(直接初始化和拷贝初始化):内置类型根据给定参数初始化;类类型由特定的构造函数初始化。
所以,类对象通过构造函数初始化,如果缺少某种构造函数,则不能进行某种初始化。
----------------------------------------------------------------------------------------------------------------------
变量(无论内置类型或类类型、单个或数组)如果不显示初始化,则采用默认初始化;局部静态变量则采用值初始化。
int val; int val[10];
void func(){ int val2; static int val3; }
void func(){ int val2[10]; static int val3[10]; }
// val(无论单个对象获数组,默认初始化)值为0, val2(...默认初始化)值未定义! val3(...值初始化)值为0
// 类类型的默认初始化和值初始化都是通过默认构造函数。
动态分配的变量(无论内置类型或类类型、单个或数组)默认情况下采用默认初始化,在类型后加单个括号以采用值初始化。
void func()
{
int *pobj = new int; int *parr = new int[10];
int *pobj2 = new int(); int *parr2 = new int[10]();
}
// pobj 指向的对象值未定义! parr 指向的数组的元素值未定义!
// pobj2 指向的对象值为0。 parr2 指向的数组的元素值都为0
新标准的初始化列表可对单个或数组对象(无论是否动态分配)进行列表初始化。若为单个对象,则初始化列表只能包含0个或1个初始值;若为数组,则列表中初始值数量不超过数组维度,如果维度比提供的初始值数量大,则用提供的初始值初始化靠前的元素,剩下的元素被值初始化。
int val {1}; int arr[10] = {1,2,3};
int *val = new val{1}; int *arr = new arr[10]{1,2,3};
// val = 1; arr = 1,2,3,0,0,0,0,0,0,0
------------------------------------------------------------------------------------------------------------------
类对象通过构造函数进行初始化的。构造函数允许有一个初始值列表。对于类的数据成员,如果没有在构造函数的初始值列表中显示地初始化成员,则该成员将在构造函数体之前执行默认初始化(如果存在类内初始值,用它来初始化成员,否则默认初始化)。随着构造函数体一开始执行,初始化就完成了。