欢迎来到天天文库
浏览记录
ID:1196463
大小:49.50 KB
页数:6页
时间:2017-11-08
《如何理解拷贝构造函数》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库。
1、我的心得:对结构和对象的参数传递和函数返回,尽量用引用,不要用值传递,一是可以节省内存开销,二是避免再创造临时对象或结构时,引起错误(特别是包含动态分配成员时)拷贝构造函数 拷贝构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构建及初始化。其唯一的参数(对象的引用)是不可变的(const类型)。此函数经常用在函数调用时用户定义类型的值传递及返回。拷贝构造函数要调用基类的拷贝构造函数和成员函数。如果可以的话,它将用常量方式调用,另外,也可以用非常量方式调用。一般来说,调用拷贝构造函数的情形 在C++中,下面三种对象需要调用拷贝构造函数:
2、 1)一个对象以值传递的方式传入函数体; 2)一个对象以值传递的方式从函数返回; 3)一个对象需要通过另外一个对象进行初始化; 如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作符共同实现的。描述拷贝构造函数和赋值运算符的异同的参考资料有很多。 拷贝构造函数不可以改变它所引用的对象,其原因如下:当一个对象以传递值的方式传一个函数的时候,拷贝构造函数自动的被调用来生成函数中的对象。如果一个对象是被传入自己的拷贝构造函数,它
3、的拷贝构造函数将会被调用来拷贝这个对象这样复制才可以传入它自己的拷贝构造函数,这会导致无限循环直至栈溢出(StackOverflow)。除了当对象传入函数的时候被隐式调用以外,拷贝构造函数在对象被函数返回的时候也同样的被调用。隐式的拷贝构造函数 如果在类中没有显式的声明一个拷贝构造函数,那么,编译器会自动生成一个来进行对象之间的位拷贝(BitwiseCopy)。这个隐含的拷贝构造函数简单的关联了所有的类成员。注意到这个隐式的拷贝构造函数和显式声明的拷贝构造函数的不同在于对成员的关联方式。显式声明的拷贝构造函数关联的只是被实例化的类成员的缺省构造函数,除非另外一个构造函
4、数在类初始化或构造列表的时候被调用。 拷贝构造函数使程序更有效率,因为它不用再构造一个对象的时候改变构造函数的参数列表。设计拷贝构造函数是一个良好的风格,即使是编译系统会自动为你生成默认拷贝构造函数。事实上,默认拷贝构造函数可以应付许多情况。示例 以下讨论中将用到的例子: classCExample { public: CExample(){pBuffer=NULL;nSize=0;} ~CExample(){deletepBuffer;} voidInit(intn){pBuffer=newchar[n];nSize=n;} private: ch
5、ar*pBuffer;//类的对象中包含指针,指向动态分配的内存资源 intnSize; }; 这个类的主要特点是包含指向其他资源的指针。 pBuffer指向堆中分配的一段内存空间。 intmain(intargc,char*argv[]) { CExampletheObjone; theObjone.Init(40); //现在需要另一个对象,需要将他初始化成对象一的状态 CExampletheObjtwo=theObjone; ... } 语句"CExampletheObjtwo=theObjone;"用theObjone初始化theObj
6、two。 其完成方式是内存拷贝,复制所有成员的值。 完成后,theObjtwo.pBuffer==theObjone.pBuffer。 即它们将指向同样的地方,指针虽然复制了,但所指向的空间并没有复制,而是由两个对象共用了。这样不符合要求,对象之间不独立了,并为空间的删除带来隐患。所以需要采用必要的手段来避免此类情况。 回顾一下此语句的具体过程:首先建立对象theObjtwo,并调用其构造函数,然后成员被拷贝。 可以在构造函数中添加操作来解决指针成员的问题。 所以C++语法中除了提供缺省形式的构造函数外,还规范了另一种特殊的构造函数:拷贝构造函数,上面的语句
7、中,如果类中定义了拷贝构造函数,这对象建立时,调用的将是拷贝构造函数,在拷贝构造函数中,可以根据传入的变量,复制指针所指向的资源。 拷贝构造函数的格式为:构造函数名(对象的引用) 提供了拷贝构造函数后的CExample类定义为: classCExample { public: CExample(){pBuffer=NULL;nSize=0;} ~CExample(){deletepBuffer;} CExample(constCExample&);//拷贝构造函数 voidInit(intn){pBuffer=newch
此文档下载收益归作者所有