构造函数的成员初始化列表 (二)

根据 Effective C++,类的成员变量最好 都用成员列表初始化 的方法进行初始化,对内置类型没什么不同,但对类对象会提高效率。 成员初始化顺序是其声明的顺序,不是初始化列表中的顺序,二者最好一致

构造函数内赋值成员变量,先调用默认构造函数,再调用赋值运算符。 如果用成员列表初始化, 只调用拷贝构造函数,提高了效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Derived : public Base
{
public:
Derived();
Derived(Base obj)
{
m_b = obj;
cout<<"derived constructor"<<endl;
}
~Derived();
Derived(const Derived& obj);
Derived& operator=(const Derived& obj);

private:
Base m_b;
};

实际调用:

1
2
3
Base b;
cout<<"----------------"<<endl;
Derived d(b);

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
base constructor
----------------
base copy constructor
base constructor
base constructor
base operator =
derived constructor
base destructor
----------------
derived destructor
base destructor
base destructor
base destructor

第一行是Base b的结果,第二行是运行构造函数时,b传递的参数副本,所以调用copy构造函数;
第三行是成员变量m_b的构造函数; 第四行是运行派生类的构造函数前先运行的基类构造函数;
第五行就是=运算符; 析构过程就简单了,不再分析



但实际中一般不这么用,Derived的成员变量会是Base* m_b,此时的调用是这样的:

1
2
3
4
5
Base *b = new Base();
Derived d(b);

delete b;
b = NULL;

结果是:

1
2
3
4
5
6
7
8
base constructor
----------------
base constructor
derived constructor
base destructor
----------------
derived destructor
base destructor

这样简单多了