最近两个周,一直在断断续续的看这些东西,《Effective c++》,再加上杨老师的不间断洗脑。虽然迷迷糊糊,却也似乎有了几分眉目。
让我先整理下脑袋,の,还有思路。。估计后续要不断的修改这篇文章了。学渣的痛,好痛,23333.。。
首先,需要注意的是,每个类只有一个析构函数和一个赋值函数,但却可以有多个构造函数(包含一个拷贝构造函数,其他的称为普通构造函数)。如果自己不编写这几个函数,编译器会自动为A产生四个缺省函数,编译器默认的构造函数指的是不带有参数或者说所有参数都是缺省值的构造函数。
A(void); // 缺省的无参数构造函数
A(const A &a); // 缺省的拷贝构造函数
~A(void); // 缺省的析构函数
A & operate =(const A &a); // 缺省的赋值函数
科普一些小知识:
关于位拷贝与值拷贝:位拷贝拷贝的是地址,而值拷贝则拷贝的是内容。编译器一般会默认进行位拷贝。
关于深拷贝与浅拷贝:简言之,如果一个类拥有资源,当这个类的对象发生复制过程的时候,若资源进行重新分配,就是深拷贝。否则,即为浅拷贝。
拷贝构造函数:以同型对象初始化自我对象;
拷贝赋值函数:从另一个同型对象中拷贝其值到自我对象。
咳咳,功课做完了我们就要开始进入正文啦~~看我认真脸
当一个新对象被定义时,会调用构造函数,如Widget w3 = w2;如果没有新对象被定义,如w1 = w2,则一定会调用赋值函数。构造函数是一种特殊的成员函数,无返回值,它的作用有三个:
创建对象;
初始化对象;
进行类型转换;
接下来让我们开始看一些需要重点注意的地方。定义一个类:错误示范
class String{ private: char *str; public: String(char *p= NULL) { if(p != NULL) { str = new char[strlen(p)+1]; strcpy(str,p); } else { str = NULL; } }
~String() { if(str != NULL) { delete []str; } str = NULL; }//析构函数
当类中成员有指针时,直接用缺省的拷贝构造函数,会产生很多很多问题。当一个类的两个对象进行赋值操作时,默认位拷贝,两个指针会指向同一块区域,虽然内容被改掉,但该对象的指针原来所指向的内存区域未释放,造成内存泄露,这是问题1;其二,两个指针指向同一块区域的话,任何一方的改变都会影响另一方。当对象被析构时,该区域会被释放两次。
多么可怕啊,啧啧啧
为什么说拷贝构造函数一定要是引用?如果拷贝构造函数的半数不是一个引用,那么就相当于采用了传指的方式,而传值的方式会调用该类的拷贝构造函数,从而造成无尽递归的调用拷贝构造函数,因此拷贝构造函数的参数必须是一个引用。修改该类的拷贝构造函数,构造函数,赋值函数。