为了正常的体验网站,请在浏览器设置里面开启Javascript功能!
首页 > 拷贝构造函数

拷贝构造函数

2018-05-02 18页 doc 37KB 9阅读

用户头像

is_589748

暂无简介

举报
拷贝构造函数拷贝构造函数 拷贝构造函数详解C++ 分类: C/C++ 2011-02-23 13:3932890人阅读评论(76)收藏举报 c++funclass编译器deletec 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: [c-sharp]view plaincopy , int a = 100; , int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。 下面看一个类对象拷贝的简单例子。 [c-sharp]view plainco...
拷贝构造函数
拷贝构造函数 拷贝构造函数详解C++ 分类: C/C++ 2011-02-23 13:3932890人阅读评论(76)收藏举报 c++funclass编译器deletec 一. 什么是拷贝构造函数 首先对于普通类型的对象来说,它们之间的复制是很简单的,例如: [c-sharp]view plaincopy , int a = 100; , int b = a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量。 下面看一个类对象拷贝的简单例子。 [c-sharp]view plaincopy , #include , using namespace std; , , class CExample { , private: , int a; ? public: ,, //构造函数 ,, CExample(int b) ,, { a = b;} ,, ,, //一般函数 ,, void Show () ,, { ,, cout< ,? using namespace std; ,, ,, class CExample { ,, private: ,, int a; ,, public: ,, //构造函数 ,, CExample(int b) ,, { a = b;} ,, ,? //拷贝构造函数 ,, CExample(const CExample& C) ,, { ,, a = C.a; ,, } ,, ,, //一般函数 ,, void Show () ,, { ,, cout<
,那就错了,让我们来考虑以下一段代码:[c-sharp]view plaincopy ,,, class Rect ,,, { ,,, public: ,,, Rect() // 构造函数,计数器加1 ,,, { ,,, count++; ,,, } ,,, ~Rect() // 析构函数,计数器减1 ,,, { ,,? count--; ,,, } ,,, static int getCount() // 返回计数器的值 ,,, { ,,, return count; ,,, } ,,, private: ,,, int width; ,,, int height; ,,, static int count; // 一静态成员做为计数器 ,,? }; ,,, ,,, int Rect::count = 0; // 初始化计数器 ,,, ,,, int main() ,,, { ,,, Rect rect1; ,,, cout<<"The count of Rect: "<内容
没有进行正确的操作。我们来分析一下: 在运行定义rect1对象后,由于在构造函数中有一个动态分配的语句,因此执行后的内存情况大致如下: 在使用rect1复制rect2时,由于执行的是浅拷贝,只是将成员的值进行赋值,这时 rect1.p= rect2.p,也即这两个指针指向了堆里的同一个空间,如下图所示: 当然,这不是我们所期望的结果,在销毁对象时,两个对象的析构函数将对同一个内存空间释放两次,这就是错误出现的原因。我们需要的不是两个p有相同的值,而是两个p指向的空间有相同的值,解决就是使用“深拷贝”。 3. 深拷贝 在“深拷贝”的情况下,对于对象中动态成员,就不能仅仅简单地赋值了,而应该重新动态分配空间,如上面的例子就应该按照如下的方式进行处理: [c-sharp]view plaincopy ,,, class Rect ,,, { ,,, public: ,,, Rect() // 构造函数,p指向堆中分配的一空间 ,,? { ,,, p = new int(100); ,,, } ,,, Rect(const Rect& r) ,,, { ,,, width = r.width; ,,, height = r.height; ,,, p = new int; // 为新对象重新动态分配空间 ,,, *p = *(r.p); ,,, } ,,? ~Rect() // 析构函数,释放动态分配的空间 ,,, { ,,, if(p != NULL) ,,, { ,,, delete p; ,,, } ,,, } ,,, private: ,,, int width; ,,, int height; ,,? int *p; // 一指针成员 ,,, }; 此时,在完成对象的复制后,内存的一个大致情况如下: 此时rect1的p和rect2的p各自指向一段内存空间,但它们指向的空间具有相 同的内容,这就是所谓的“深拷贝”。 3. 防止默认拷贝发生 通过对对象复制的分析,我们发现对象的复制大多在进行“值传递”时发 生,这里有一个小技巧可以防止按值传递——声明一个私有拷贝构造函数。甚至 不必去定义这个拷贝构造函数,这样因为拷贝构造函数是私有的,如果用户试图 按值传递或函数返回该类对象,将得到一个编译错误,从而可以避免按值传递或 返回对象。 [c-sharp]view plaincopy ,,, // 防止按值传递 ,,, class CExample ,,, { ,,, private: ,,, int a; ,,, ,,, public: ,,, //构造函数 ,,? CExample(int b) ,,, { ,,, a = b; ,,, cout<<"creat: "<
/
本文档为【拷贝构造函数】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索