代码改变世界

c++类初始化(Effective c++学习总结)

2011-08-11 10:57  悠悠白云  阅读(284)  评论(0)    收藏  举报

初始化(initialization)是给对象初值的过程,对用户自定义类型的对象而言,初始化有构造函数执行。构造函数分为默认构造和拷贝构造函数。

默认构造函数(default constructor)是一个被调用而不带任何实参的函数。这样的函数要么没有参数,要么就是每个参数都有缺省值。如定义一个类变量,编译器调用默认的构造函数给他赋值。

举个例子来说:

class A{

public:

A();                        //默认构造函数,因为没有参数

};

class B{

public B(int x=0,bool b=true);   //带缺省参数的构造函数,兼具默认构造函数的功能,因为调用的时候可以不传参

};

拷贝构造函数(copy constructor)是用来“以同类型对象初始化自我对象”,他具有构造函数的定义形式,但参数一般是该类类型的引用。

另外我们一般也通过拷贝赋值操作符对类成员进行赋值。我通常把这两个混淆,举个例子:

class C{

C();

C(const C & c);            //拷贝构造函数

C & operator=(const C & c);  //拷贝赋值操作

};

C c1;   //调用了默认构造函数

C c2(c1);  //调用拷贝构造函数;

c1=c2;   //调用赋值操作函数

C c3=c1; //此时调用拷贝构造函数

很神奇吧。拷贝构造和赋值操作很神似。究竟如何区分它们呢?

如果=的左边是一个未被定义的对象,则调用的是拷贝构造函数,因为任何一个类成员创建时都会调用构造函数,如果已经定义了,那么用的赋值操作。

注意了,拷贝赋值操作符返回的是类引用,这样做的目的是为了可以传递赋值如c1=c2=c3,但是参数为什么也是引用类型呢?这样做有很多好处。

要知道c++在函数调用时传递的是实参的副本,即编译器调用拷贝构造函数以实参为参数构造了一个新的对象,这个对象作为函数的参数。函数返回时析构这个对象。因而带来了内存开销和时间代价。对那些复杂的对象,这个弊端就显而易见了。

而且如果用子类作为实参传递给基类形参是会发生截断,得到与愿望相反的结果。因而此时最好用引用传递。

第三个是如果对象有动态分配的数据成员,在释放实参副本时会把实参的动态部分也释放掉。造成内存泄漏。