C++浅拷贝的另一种实现方式
2016-12-11 21:38
211 查看
C++的浅拷贝,虽然编译器已经默认帮我们实现了,但是作为一个技术人员应该要具备有最基本的“黑客精神”,说到C++浅拷贝的实现,大家第一反应就是通过拷贝构造函数实现成员变量的直接赋值。也就是如下的代码:
当然写到这里,如果就是这么简单的话就没有必要写这篇博客了,浅拷贝也叫按位拷贝,就是将一个对象的内存空间的内容远远本本拷贝过去。多说一点因为对象的指针成员所指向的内存不属于该对象的内容,不占用对象的内存空间,所以浅拷贝不会将对象中指针成员所指向的内存复制过去;就好像上面的例子如果执行浅拷贝,那么拷贝的只是arrayA本身,而它所指向的40个整形的内存空间是不会被拷贝过去的;因此浅拷贝的源对象如果被析构之后,复制对象的中的指针成员就会成为空悬指针(Dangling Pointer)。
扯远了,那按位拷贝从语义上来说就是,在内存空间中以byte为单位将内存复制到另一个内存空间。所以要怎么实现呢,那我们可以参考字符串拷贝,知道源内存首地址,知道内存空间大小,知道目标内存地址就可以连续地拷贝过去了。参照下列代码:
上面的版本为了看清楚明白其中的原理再简化的版本
再扯一波,刚刚说到const指针this, const指针通常指的是指针本身不能被修改,但是其指向的内容可以被修改,this就是这种类型。还有一种是指向const内容的指针,这种这种指针本身可以被修改,但是其指向的内容不可以被修改。
具体的声明如下例如:
第一种:
第二种:
对于第一种如果我们要修改const内容该怎么办,那就是用const_cast<>(data)来去掉const属性
class A { public: A() { arrayA = new int [size];//内存分配 for( size_t i = 0;i<size;i++) { arrayA[i] = i; } ~A() { delete arrayA; } A(const A& object)//复制构造函数 { this->arrayA = object.arrayA;//成员变量直接复制,实现浅拷贝 } private: const size_t size= 40; int *arrayA; }
当然写到这里,如果就是这么简单的话就没有必要写这篇博客了,浅拷贝也叫按位拷贝,就是将一个对象的内存空间的内容远远本本拷贝过去。多说一点因为对象的指针成员所指向的内存不属于该对象的内容,不占用对象的内存空间,所以浅拷贝不会将对象中指针成员所指向的内存复制过去;就好像上面的例子如果执行浅拷贝,那么拷贝的只是arrayA本身,而它所指向的40个整形的内存空间是不会被拷贝过去的;因此浅拷贝的源对象如果被析构之后,复制对象的中的指针成员就会成为空悬指针(Dangling Pointer)。
扯远了,那按位拷贝从语义上来说就是,在内存空间中以byte为单位将内存复制到另一个内存空间。所以要怎么实现呢,那我们可以参考字符串拷贝,知道源内存首地址,知道内存空间大小,知道目标内存地址就可以连续地拷贝过去了。参照下列代码:
class A { public: A() { arrayA = new int [size];//内存分配 for( size_t i = 0;i<size;i++) { arrayA[i] = i; } ~A() { delete arrayA; } A(const A& object)//复制构造函数 { char* source = &object; //得到目标地址,赋值给char指针目的是为了在指针运算时让系统按1个字节去递增 char* dest = (char*)this; /*获取目标地址,也就是本对象的地址,注意this指针是一个常量,且是一个非左值不能被赋值和修改,只能读取,所以要修改本对象的内容,只能通过获取本对象的地址,并将内容拷贝到本对象的地址中*/ for(size_t i = 0; i<sizeof(A);i++) *(dest+i) = *(source+i);//内存拷贝,完成从源对象到目标对象的内存复制。 } private: const size_t size= 40; int *arrayA; }
上面的版本为了看清楚明白其中的原理再简化的版本
A(const A &object) { memcpy(this, &object,sizeof(A)); //呵呵就是这么简单 }
再扯一波,刚刚说到const指针this, const指针通常指的是指针本身不能被修改,但是其指向的内容可以被修改,this就是这种类型。还有一种是指向const内容的指针,这种这种指针本身可以被修改,但是其指向的内容不可以被修改。
具体的声明如下例如:
第一种:
const int *p = new int(10);//const在指针的左边,声明一个指针指向const int。 *p = 20;//错误,const内容不能被修改 p++//正确,指针不是const
第二种:
int * const p = new int(10);//const在指针的右边,声明一个const指针指向int。 *p = 20;//正确,内容不是const p++//错误,指针是const const int* const p;//内容和指针都是const都不能被修改
对于第一种如果我们要修改const内容该怎么办,那就是用const_cast<>(data)来去掉const属性
const int *p = new int(10);//const在指针的左边,声明一个指针指向const int。 *p = 20;//错误,const内容不能被修改 int *unconst_p = const_cast<int*>(p); *unconst_p = 20;//去掉const属性之后正确
相关文章推荐
- 另一种ASP.NET与Ajax 的实现方式--jQuery
- WinCE5.0/6.0下命令行实现自动编译及另一种方式命令行编译
- 看板,敏捷的另一种实现方式
- 另一种校验同步报文的实现方式
- supermap学习系列(八)——上一篇的另一种实现方式(给要素图层SuperMap.Layer.Vector注册事件)
- 解决用序列化方式实现对象拷贝时出的异常解决方法
- 线程:创建线程有两种方式,一种是继承Thread类,另一种是实现Runnable接口。代码如下:
- 继承的另一种实现方式- 通过复制属性实现继承
- Android ListView优化的另一种实现方式
- Linux操作系统备份之三:通过二进制拷贝(dd)方式实现Linux操作系统数据的备份
- 二阶电路零状态响应的另一种实现方式
- jQuery仿手风琴效果另一种实现方式,非插件.原创
- C#对象的浅拷贝,深拷贝及利用序列化等多种方式实现深拷贝
- 看板,敏捷的另一种实现方式
- wpf 自定义窗体 另一种实现方式
- while select 的另一种实现方式"Next Table"
- 促进AlertDialog通用化的另一种实现方式
- sping中TransactionTemplate对Template模式的另一种实现方式
- js 中多维数组的深拷贝的多种实现方式
- Java对PHP服务器hmac_sha1签名认证方法的匹配实现 的另一种方式