欢迎来到天天文库
浏览记录
ID:10777063
大小:36.38 KB
页数:28页
时间:2018-07-08
《[学习c++]构造函数 析构函数和赋值操作符》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、几乎所有的类都有一个或多个构造函数,一个析构函数和一个赋值操作符。这没什么奇怪的,因为它们提供的都是一些最基本的功能。构造函数控制对象生成时的基本操作,并保证对象被初始化;析构函数摧毁一个对象并保证它被彻底清除;赋值操作符则给对象一个新的值。在这些函数上出错就会给整个类带来无尽的负面影响,所以一定要保证其正确性。本章我将指导如何用这些函数来搭建一个结构良好的类的主干。构造函数,析构函数和赋值操作符几乎所有的类都有一个或多个构造函数,一个析构函数和一个赋值操作符。这没什么奇怪的,因为它们提供的都是一些最基本的功能。构造函数控制对象生成时的基本操作,并保证对象被初始化;析构函
2、数摧毁一个对象并保证它被彻底清除;赋值操作符则给对象一个新的值。在这些函数上出错就会给整个类带来无尽的负面影响,所以一定要保证其正确性。本章我将指导如何用这些函数来搭建一个结构良好的类的主干。条款11:为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符看下面一个表示string对象的类://一个很简单的string类classstring{public: string(constchar*value); ~string(); ... //没有拷贝构造函数和operator=private: char*data;};
3、string::string(constchar*value){ if(value){ data=newchar[strlen(value)+1]; strcpy(data,value); } else{ data=newchar[1]; *data=' '; }}inlinestring::~string(){delete[]data;}请注意这个类里没有声明赋值操作符和拷贝构造函数。这会带来一些不良后果。如果这样定义两个对象:stringa("hello");stringb("world");其结果就会如下所示:a: data——>"hello "
4、b: data——>"world "对象a的内部是一个指向包含字符串"hello"的内存的指针,对象b的内部是一个指向包含字符串"world"的内存的指针。如果进行下面的赋值:b=a;因为没有自定义的operator=可以调用,c++会生成并调用一个缺省的operator=操作符(见条款45)。这个缺省的赋值操作符会执行从a的成员到b的成员的逐个成员的赋值操作,对指针(a.data和b.data)来说就是逐位拷贝。赋值的结果如下所示:a: data-------->"hello " /b: data--/ "world "这种情况下至少
5、有两个问题。第一,b曾指向的内存永远不会被删除,因而会永远丢失。这是产生内存泄漏的典型例子。第二,现在a和b包含的指针指向同一个字符串,那么只要其中一个离开了它的生存空间,其析构函数就会删除掉另一个指针还指向的那块内存。stringa("hello"); //定义并构造a{ //开一个新的生存空间 stringb("world"); //定义并构造b ... b=a; //执行operator=,
6、 //丢失b的内存} //离开生存空间,调用 //b的析构函数stringc=a; //c.data的值不能确定! //a.data已被删除例子中最后一个语句调用了拷贝构造函数,因为它也没有在类中定义,c++以与处理赋值操作符一样的方式生成一个拷贝构造函数并执行相同的动作:对对象里的
7、指针进行逐位拷贝。这会导致同样的问题,但不用担心内存泄漏,因为被初始化的对象还不能指向任何的内存。比如上面代码中的情形,当c.data用a.data的值来初始化时没有内存泄漏,因为c.data没指向任何地方。不过,假如c被a初始化后,c.data和a.data指向同一个地方,那这个地方会被删除两次:一次在c被摧毁时,另一次在a被摧毁时。拷贝构造函数的情况和赋值操作符还有点不同。在传值调用的时候,它会产生问题。当然正如条款22所说明的,一般很少对对象进行传值调用,但还是看看下面的例子:voiddonothing(stringlo
此文档下载收益归作者所有