这里概括性的讨论了C++中的初始化规则,一些具体类型还需单独讨论。
1、当对象在创建时获得了一个特定的值,我们说这个对象被初始化了。用于初始化变量的值可以是任意复杂的表达式。
2、初始化不是赋值,初始化的含义是创建变量时赋予其一个初始值,而赋值的含义是把对象的当前值擦除,以一个新值来代替。
3、初始化可分为直接初始化和拷贝初始化:
3.1、若使用=初始化一个变量,则执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去。
int i=0;
3.2、如果不使用等号,则执行的是直接初始化。
int i(0);
3.2.1、当初始值只有一个时,使用直接初始化和拷贝初始化都行。若初始化要用到的值有多个,一般只能使用直接初始化。(如果非要非要用拷贝初始化的方式初始化需多个值进行初始化的对象,就需要显式的用直接初始化方式创建一个临时对象用于拷贝。)
3.2.2某些类类型可能存在特殊的直接初始化方式,具体将在针对于某个类类型的文章中介绍。
4、列表初始化(C++11):无论是初始化对象还是某些时候为对象赋新值,都可以使用花括号将初始值括起来进行初始化。此时等号大部分情况下都可有可无,这一点区别于C语言。
int i{0};//初始化
int ii={i};//初始化
int j=1;
j={i};//赋值
4.1、使用列表初始化且初始值存在丢失信息的风险,编译器将报错
long double pi{3.14159265359};
int i{pi};//错误:转换为执行,因为存在信息丢失风险
int j=pi;//正确:转换执行且确实丢失了信息
4.2、当初始值有多个时,可以通过逗号将不同的初始值隔开。
vector<string> v{"a","an","the"};
5、默认值初始化:
5.1、如果定义变量时没有指定初值,则变量被默认初始化。
5.2、默认值取决于变量的类型,同时定义变量的位置也会对此有影响。
5.2.1、如果是内置类型的变量未被显式初始化,它的值由定义的位置决定。
定于与任何函数体之外的变量被初始化为0。
定义在函数体内部的内置变量将不被初始化,此时它为未知值。
5.2.2、每个类各自决定其初始化对象的方式。而且是否允许不经初始化就定义对象也由类自己决定。如果类允许这种行为,它将决定对象的初始值是什么。若果不支持这种行为,默认值初始化则会引发错误。绝大多数类都支持无需显示初始化而定义对象,这样的类提供了一个合适的默认值。如string类规定如果没有指定初始值则生成一个空串。