以前在写代码时用初始化列表,因为前辈们说效率更高,也没有去想为什么。
最近看<<effective C++>>Item4: 确保对象在使用前被初始化,恍然大悟。
如果使用赋值的方式在构造函数中初始化“类成员变量”,会先调用这个“类成员变量”类的默认构造函数,再调用赋值函数。
而使用初始化列表初始化“类成员变量”,只会调用这个“类成员变量”类的拷贝构造函数。
“赋值方式初始化”比“初始化列表”多调用一次默认构造函数,对于数据的初始化、赋值都会新去开辟内存空间(可以参考 拷贝构造函数),所以初始化列表的效率更高。
详见下面测试代码。
一点感想:
C++中每一个小功能点都有它的意义。
最近看<<effective C++>>Item4: 确保对象在使用前被初始化,恍然大悟。
如果使用赋值的方式在构造函数中初始化“类成员变量”,会先调用这个“类成员变量”类的默认构造函数,再调用赋值函数。
而使用初始化列表初始化“类成员变量”,只会调用这个“类成员变量”类的拷贝构造函数。
“赋值方式初始化”比“初始化列表”多调用一次默认构造函数,对于数据的初始化、赋值都会新去开辟内存空间(可以参考 拷贝构造函数),所以初始化列表的效率更高。
详见下面测试代码。
一点感想:
C++中每一个小功能点都有它的意义。
C++的学习就像射箭一样,只有在不断的炼习中,才会由拖把到10环、9环、8环,直到0环的精准。
#include <iostream>
using namespace std;
class A
{
public:
A()
{
cout<<"Default Constructor, A()"<<endl;
}
A(A &a)
{
cout<<"Copy Constructor A"<<endl;
}
A &operator=(A &a)
{
cout<<"Assignment Constructor (=) A"<<endl;
}
};
class B
{
public:
B()
{
cout<<"Default Constructor, B()"<<endl;
}
B(B &b)
{
cout<<"Copy Constructor B"<<endl;
}
B &operator=(B &b)
{
cout<<"Assignment Constructor (=) B"<<endl;
}
};
class C
{
public:
//a_的初始化会调用A的拷贝构造函数
//b_的初始化会调用B的默认构造函数、赋值构造函数
//即使没有此(带参)构造函数,a_和b_也会调用其默认构造函数初始化
//补充:成员变量的初始化(列表)顺序是变量的声明顺序,即使是这样的C(A &a, B &b):b_(b),a_(a)
C(A &a, B &b):a_(a)
{
b_ = b;
}
private:
A a_;
B b_;
};
int main()
{
A a;
B b;
C c(a, b);
}