定义一个变量,就是在内存中为你定义的这个变量开辟一段内存空间,如果这个变量没有初始化,那么系统会随机给这个变量赋一个值,这个值我一般称它为"垃圾数"。
没有初始化的变量我认为它是没有意义的,是在浪费内存,就比如人刚出生的时候上帝需要给他赋予点东西,比如条件反射,比如哭,比如吮吸........这样人的意义得以体现。
对于类的成员来说,我们最好的做法就是在构造函数中对每一个类成员进行初始化。
我们来看一个简单的例子:
class name
{
public:
name(int aa, int bb)
{}
private:
int a;
int b;
};
上面例子中的变量 a 和 b 的值都没有在构造函数中初始化,这时候它们的值就会是一个"垃圾数",我们稍微改一下:
class name
{
public:
name(int aa, int bb):a(aa)
{
b = bb;
}
private:
int a;
int b;
};
可以看到 a 的值是用初始化列表的方式进行初始化,而 b 的值是通过构造函数的参数进行赋值。
在类对象调用构造函数的时候,以上两种方式都可以确保 a 和 b 的值是可以确定的,但是初是初始化和赋值两种方式是有区别的:
1. 初始化发生的时机肯定比赋值早。初始化会在程序刚开始运行的时候发生,而赋值是只有在程序执行到这条语句才会发生。
2. 初始化的执行效率要比赋值高。类成员在构造函数中执行的赋值语句之前已经被系统进 行了初始化,当执行赋值的时候就需要抹掉之前default的初始化的数据,这样就相当于多做了一次无用功,而构造函数中运行的初始化列表则不需要做这次无用功。
3. 常量成员和引用成员只能使用初始化列表。这是c++的语法。
class name
{
public:
name(int aa, int bb):b(bb),a(aa)
{}
private:
int const a;
int &b;
};
代码中的类成员 a 和 b 是必须使用初始化列表初始化的,这是c++语法规定的。
另外,类成员的初始化的顺序的固定的:如果有基类的话,先初始化基类,然后按照类中声明的顺序去初始化派生类中的类成员。上述代码中可以看到,构造函数初始化列表是先写 b 后写 a,即使是这样也是会按声明的顺序先初始化 a 后初始化 b。
我们来做一个实验就可以彻底明白:
class Name
{
public:
Name():b(2),a(b + 2)
{}
void print()
{
cout << "a = " << a << " , b = " << b << endl;
}
private:
int const a;
int b;
};
int main()
{
Name Leon;
Leon.print();
return 0;
}
编译后的结果为:
结果很明显,当初始化 a 的时候,b还没被初始化为2,b还是个垃圾数,所以最终打印的 a 的值依然是个垃圾数,b 则后面被初始化为 2。
微信公众号:混说Linux