C++ Primer里说过,在C++中,初始化不等于赋值,初始化是指创建变量并给变量赋初值,而赋值是指擦除变量的当前值并用新值替换。C++中有两种初始化方法,直接初始化和复制初始化。直接初始化是指使用 Object obj(patamer)这样的语句,Object可以是内置类型或者用户自定义的类类型;而复制初始化是指Object obj = obj1。
1)内置类型的初始化
以int型为例:
int a = 5 // 复制初始化
int b(5); // 直接初始化
对于内置类型来说这两种初始化没有任何差别。
2)类对象的初始化
class Base
{
public:
Base() {cout<<"Base::Base()"<<endl; } // 默认构造函数
Base(int i) {cout<<"Base::Base(int i)"<<endl; } // 带一个整形参数的构造函数
Base(const Base& base) {cout<<"Base(const Base& base)"<<endl; } // 拷贝构造函数
Base& operator= (const Base& base) { cout<<"operator="<<endl; return *this;} // 复制操作符
};
以类Base为例,首先声明,以上代码并为考虑成员函数的正确与否。
Base base1; //调用默认构造函数
Base base2(1); //调用带一个整形参数的构造函数
Base base3(base2);// 调用拷贝构造函数
Base base4 = base1;//调用拷贝构造函数
总之,对于类类型,直接初始化调用默认构造函数或者与初始化时提供的参数相匹配的构造函数(注意,包括拷贝构造函数);而复制初始化则调用拷贝构造函数。
说到这里,顺便提下构造函数初始化列表
3)构造函数初始化列表
假设有一个类:
class Test
{
public:
Test(){ _base = Base();}
Test(int i) : _base(i) {};
Test(const Base& base) : _base(base) {};
Base _base;
};
同样C++ primer中,说过这样一句话,大概意思是,构造函数分为两部分:初始化和赋值,在构造函数初始化列表里进行的是初始化,调用与提供的参数匹配的构造函数来初始化成员变量。而在构造函数的一对大括号之间,则进行的是赋值,既然是赋值,那么就说明已经进行了初始化,这个初始化过程是通过调用默认构造函数来实现的,在大括号里面进行的是赋值操作,调用的是赋值操作符。
如:
Test = t1; // 先调用默认构造函数Base()初始化_base,然后在调用复制操作符对_base进行赋值
Test t2(1); // 直接调用带一个整形参数的构造函数Base(int i)初始化_base
Base base5;
Test t3(base5);//直接调拷贝构造函数Base(const Base& base)初始化_base
注意:如果成员变量所属的类如果没有默认构造函数,那么就必须采用构造函数初始化列表的方式进行初始化。
对于用户自定义的类类型的成员变量来说,应该采用初始化列表的方式进行初始化,这样就省略了赋值的过程,提高了效率;而对于内置内型,差别不大。