【转】C++中的位拷贝与值拷贝
【转】http://blog.csdn.net/liam1122/article/details/1966617
为了便于说明我们以String类为例:
首先定义String类,而并不实现其成员函数。
Class String{
public:
String(const char *ch=NULL);//默认构造函数
String(const String &str);//拷贝构造函数
~String(void);
String &operator=(const String &str);//赋值函数
private:
char *m_data;
};
位拷贝拷贝的是地址,而值拷贝则拷贝的是内容。如果定义两个String对象A和B。A.m_data和B.m_data分别指向一段区域,A.m_data="windows",B.m_data=“linux";
如果未重写赋值函数,将B赋给A;则编译器会默认进行位拷贝,A.m_data=B.m_data
则A.m_data和B.m_data指向同一块区域,虽然A.m_data指向的内容会改变成"linux",但是这样容易出现这些问题:
(1):A.m_data原来指向的内存区域未释放,造成内存泄露。
(2):A.m_data和B.m_data指向同一块区域,任何一方改变都会影响另一方
(3):当对象被析构时,B.m_data被释放两次。
对于编译器,如果不主动编写拷贝函数和赋值函数,它会以“位拷贝”的方式自动生成缺省的函数。
如果重写赋值函数和拷贝构造函数后,
A.m_data=B.m_data,进行的是值拷贝,会将B.m_data的内容赋给A.m_data,A.m_data还是指向原来的内存区域,但是其内容改变。
【转】http://www.chinaitlab.com/c/ccjq/913552.html
位拷贝拷贝的是地址(也叫浅拷贝),而值拷贝则拷贝的是内容(深拷贝)。深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
位拷贝,及"bitwise assignment"是指将一个对象的内存映像按位原封不动的复制给另一个对象,所谓值拷贝就是指,将原对象的值复制一份给新对象。 在用"bitwise assignment"时会直接将对象的内存映像复制给另一个对象,这样两个对象会指向同一个内存区域,当一个对象被释放后,另一个对象的指针会成为空指针。这时,就应该编写operator=和copy constructor来实现值拷贝 .
默认的拷贝构造函数"和"缺省的赋值函数"均采用"位拷贝"而非"值拷贝"的方式来实现,倘若类中含有指针变量,这两个函数注定将出错。
当用一个已初始化过了的自定义类类型对象去初始化另一个新构造的对象的时候,拷贝构造函数就会被自动调用。也就是说,当类的对象需要拷贝时,拷贝构造函数将会被调用。以下情况都会调用拷贝构造函数:
1、一个对象以值传递的方式传入函数体
2、一个对象以值传递的方式从函数返回
3、一个对象需要通过另外一个对象进行初始化。
如果在类中没有显式地声明一个拷贝构造函数,那么,编译器将会自动生成一个默认的拷贝构造函数,该构造函数完成对象之间的位拷贝。位拷贝又称浅拷贝。自定义拷贝构造函数是一种良好的编程风格,它可以阻止编译器形成默认的拷贝构造函数,提高源码效率。
如果没有自定义复制构造函数,则系统会创建默认的复制构造函数,但系统创建的默认复制构造函数只会执行"位拷贝",即将被拷贝对象的数据成员的值一一赋值给新创建的对象,若该类的数据成员中有指针成员,则会使得新的对象的指针所指向的地址与被拷贝对象的指针所指向的地址相同,delete该指针时则会导致两次重复delete而出错。下面拿这个经典示例:
Class String{
public:
String(const char *ch=NULL);//默认构造函数
String(const String &str);//拷贝构造函数
~String(void);
String &operator=(const String &str);//赋值函数
private:
char *m_data;
};
如果以String为例定义strA和strB
int main(){
String strA("hello");
String strB("world");
strB = strA;
// 结果导致 strA 和 strB 的指针都指向了同一个地址
// 函数结束析构时
// 同一个地址被delete两次
return ;
}
如果不主动编写拷贝构造函数和赋值函数,编译器将以"位拷贝"的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误。以类String的两个对象strA,strB为例,假设strA.m_data的内容为"hello",strB.m_data的内容为"world". 现将strA赋给strB,缺省赋值函数的"位拷贝"意味着执行strB.m_data =strA.m_data.这将造成三个错误:
● strB.m_data 原有的内存没被释放,造成内存泄露;
● strB.m_data和strA.m_data指向同一块内存,strA或strB任何一方变动都会影响另一方;
● 在对象被析构时,m_data被释放了两次。
对于编译器,如果不主动编写拷贝函数和赋值函数,它会以位拷贝的方式自动生成缺省的函数。
【转】C++中的位拷贝与值拷贝的更多相关文章
- 【转载】C++中的位拷贝和值拷贝
---恢复内容开始--- 原文:C++中的位拷贝和值拷贝 原文:http://blog.csdn.net/liam1122/article/details/1966617 为了便于说明我们以Strin ...
- C语言中的位拷贝与值拷贝浅谈(转载)
注:C语言实现的PHP变量的赋值过程中,就涉及到了 深拷贝和浅拷贝 位拷贝拷贝的是地址(也叫浅拷贝),而值拷贝则拷贝的是内容(深拷贝).深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象 ...
- c++的默认构造函数 VS 深拷贝(值拷贝) 与 浅拷贝(位拷贝)
C++默认为类生成了四个缺省函数: A(void); // 缺省的无参数构造函数 A(const A &a); // 缺省的拷贝构造函数 ~A(void); // 缺省的析构函数 A & ...
- .net中String是引用类型还是值类型 以及 C#深层拷贝浅层拷贝
http://www.cnblogs.com/yank/archive/2011/10/24/2204145.html http://www.cnblogs.com/zwq194/archive/20 ...
- PowerDesigner里面将表中name列值拷贝到comment列
完整版见https://jadyer.github.io/2015/06/03/powerdesigner-copy-name-to-comment/ /** * PowerDesigner里面将表中 ...
- 深入研究js中的位运算及用法
什么是位运算? 位运算是在数字底层(即表示数字的 32 个数位)进行运算的.由于位运算是低级的运算操作,所以速度往往也是最快的(相对其它运算如加减乘除来说),并且借助位运算有时我们还能实现更简单的程序 ...
- Google Earth Engine 中的位运算
Google Earth Engine中的位运算 按位运算是编程中一个难点,同时也是在我们后续处理影像数据,尤其要使用影像自带的波段比如QA波段经常会用到的一个东西.通过按位运算我们可以筛选出我们想要 ...
- js中的位运算
按位运算符是把操作数看作一系列单独的位,而不是一个数字值.所以在这之前,不得不提到什么是"位": 数值或字符在内存内都是被存储为0和 1的序列,每个0和1被称之为1个位,比如说10 ...
- CSAPP读书随笔之一:为什么汇编器会将call指令中的引用的初始值设置为-4
CSAPP,即<深入理解计算机系统:程序员视角>第三版,是一本好书,但读起来确需要具备相当的基本功.而且,有的表述(中译文)还不太直白. 比如,第463页提到,(对于32位系统)为什么汇编 ...
随机推荐
- phpcms v9 读取地区联动菜单缓存文件
读取缓存文件的方法是 getcache() 在 phpcms\libs\functions\global.func.php 中可找到. 地区联动菜单的缓存文件是 caches\caches_link ...
- PHP获取指定年份指定月份的天数
最近写接口的时候突然发现的非常实用的php函数,在这儿分享一下: cal_days_in_month(calender,$month,$year): calender:历法,常量,如CAL_GREGO ...
- Css3执行后显示最后一针
-webkit-animation-fill-mode: both; animation-fill-mode: both;
- [资料] Apache2 的 httpd.conf 经典中文翻译
[i=s] 本帖最后由 www.PHP888.com 于 2009-5-22 13:40 编辑 [/i] # 基于 NCSA 服务的配置文件. # #这是Apache服务器主要配置文件. #它包含服务 ...
- Hive笔记--配置以及遇到的问题
ubuntu安装mysql http://www.2cto.com/database/201401/273423.html Hive安装: http://www.aboutyun.com/forum ...
- Golang http包下FileServer的使用
FileServer文档:https://godoc.org/net/http#FileServer 今天看到http的 Handle 方法,所以就像试试,就找到FileServer FileServ ...
- android弹出式菜单、弹出式对话框、弹出式窗口
http://www.open-open.com/lib/view/open1389767042601.html http://www.open-open.com/lib/view/open13321 ...
- BZOJ3390: [Usaco2004 Dec]Bad Cowtractors牛的报复
3390: [Usaco2004 Dec]Bad Cowtractors牛的报复 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 43 Solved: ...
- 部分无线终端不响应键盘事件(keydown,keypress,keyup)的解决办法
在无线侧实现搜索显示smartbox功能的时候,会对输入框绑定keydown.keyup.keypress事件,从而在检测到输入框的值发生改变时,发出请求拉取smartbox的内容. 但是,在iPho ...
- Android中ListView同过自定义布局并使用SimpleAdapter的方式实现数据的绑定
1.listview的数据填充可以通过ArrayAdapter,SimpleAdapter,也可以是一个xml文件,但是ArrayAdapter与SimpleAdapter的区别是: 2 ArrayA ...