effective cpp读书笔记1
非内置类型的成员变量最好都用初始化列表初始化,因为在构造函数执行前,会先初始化这个对象内部的成员,若是有初始化列表,则按初始化列表来初始化,若是没有,则自动执行成员的默认构造函数。看下面的例子
#include <stdio.h>
class A{
public:
int x;
A(){
printf("A default constructor\n");
}
A(int x){
printf("A constructor with par\n");
this->x = x;
}
};
class B{
public:
A a;
B(){
printf("B default constructor\n");
}
B(const A &a){
printf("B constructor with par\n");
this->a = a;
}
};
int main()
{
A a(1);
B b(a);
return 0;
}
程序的输出是
wd@ub-linux:effective_cpp$ ./a.out
A constructor with par
A default constructor
B constructor with par
可以看到先构造a(1),然后在构造b时,由于b内部有成员a,于是要先初始化a,于是调用a的默认构造函数。但实际上这一步是多余的,相当于b.a被赋值了两次。
在看下面的写法
#include <stdio.h>
class A{
public:
int x;
A(){
printf("A default constructor\n");
}
A(int x){
printf("A constructor with par\n");
this->x = x;
}
A(const A& a){
printf("A copy constructor\n");
this->x = a.x;
}
};
class B{
public:
A a;
B(){
printf("B default constructor\n");
}
B(const A &a):a(a){
printf("B constructor with par\n");
}
};
int main()
{
A a(1);
B b(a);
return 0;
}
这次的输出是
A constructor with par
A copy constructor
B constructor with par
B的构造函数中没有了赋值操作,但是把b.a的初始化放在了初始化列表里面,这样b.a就只初始化了一次。可以说这一操作是非常重要的,在一些比较大的类中,可以节省很多不必要的赋值操作。