构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:
class CExample {
public:
int a;
float b;
//构造函数初始化列表
CExample(): a(0),b(8.8)
{}
//构造函数内部赋值
CExample()
{
a=0;
b=8.8;
}
};
上面的例子中两个构造函数的结果是一样的。
上面的构造函数(使用初始化列表的构造函数)显式的初始化类的成员;
而没使用初始化列表的构造函数是对类的成员赋值,并没有进行显式的初始化。
问题1:初始化、显式初始化、隐式初始化这三个的区别
简单理解显式初始化即为手工给予初值,否则为隐式初始化,将内容设置为默认值。
自动变量在运行时进入函数的时候,才进行分配空间赋值。非自动变量会自隐式清零,而自动变量是不会自隐式清零的。若没有在定义变量时显式初始化,未赋值前,该变量的内容是不确定值。
分配空间给变量后,赋予初值称为初始化。
非自动变量是在编译期分配其空间,可以显式(即手工)给予初值,否则会隐式把该空间内所有内容设为零。
问题2:自动变量非自动变量
初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。对非内置类型成员变量,为了避免两次构造,推荐使用类构造函数初始化列表。但有的时候必须用带有初始化列表的构造函数:
自动变量(编译器自动分配内存的变量)是运行时每次进入函数时,才分配空间的。同一变量名实际上会对应不同的空间(例如考虑递归时的情况)。与非自动变量不同,自动变量是不会自隐式清零的。若没有在定义变量时显式初始化,未赋值前,该变量的内容是不确定值。
为什么要有这种区别呢?都自动清零不是更安全么?
其中一个原因是,非自动变量只有一份,可以在编译、链接及加载过程初始化其值,而没有什么运行时开销。相反,自动变量进行初始化是有运行时开销的。有时候我们的确只需为变量分配空间而不需初始化,例如sprintf(buffer, ...)中的buffer若是自动变量,为它初始化是徒劳无功的。所以C语言设计时为了性能,便容许自动变量不进行初始化。这和许多语言不一样。