C语言中的位拷贝与值拷贝浅谈(转载)
注:C语言实现的PHP变量的赋值过程中,就涉及到了 深拷贝和浅拷贝
位拷贝拷贝的是地址(也叫浅拷贝),而值拷贝则拷贝的是内容(深拷贝)。深拷贝和浅拷贝可以简单理解为:如果一个类拥有资源,当这个类的对象发生复制过程的时候,资源重新分配,这个过程就是深拷贝,反之,没有重新分配资源,就是浅拷贝。
位拷贝,及"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 0;
}
如果不主动编写拷贝构造函数和赋值函数,编译器将以"位拷贝"的方式自动生成缺省的函数。倘若类中含有指针变量,那么这两个缺省的函数就隐含了错误。以类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被释放了两次。
对于编译器,如果不主动编写拷贝函数和赋值函数,它会以位拷贝的方式自动生成缺省的函数。
另外一篇文章 http://blog.csdn.net/bluescorpio/article/details/4322682
C语言中的位拷贝与值拷贝浅谈(转载)的更多相关文章
- 【转载】C++中的位拷贝和值拷贝
---恢复内容开始--- 原文:C++中的位拷贝和值拷贝 原文:http://blog.csdn.net/liam1122/article/details/1966617 为了便于说明我们以Strin ...
- C语言中的位运算和逻辑运算
这篇文章来自:http://blog.csdn.net/qp120291570/article/details/8708286 位运算 C语言中的位运算包括与(&),或(|),亦或(^),非( ...
- C语言中两位ASCII码可以表示汉字
最近偶然有人问到这个相关字符编码的问题,所以百度了下参考了这两个资料,进行了简单分析. ******************************************************** ...
- 【转】C++中的位拷贝与值拷贝
[转]http://blog.csdn.net/liam1122/article/details/1966617 为了便于说明我们以String类为例: 首先定义String类,而并不实现其成员函数. ...
- C/C++语言中的位运算
在计算机程序中,数据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的运算和操作. 一般的位操作是用来控制硬件的,或者做数据变换使用,但是,灵活的位操作可以有效地提高程序运行的效率.C语 ...
- 关于C语言中的位运算符的学习即应用
一.运算符的种类和运算规则: & 与:全1则1,有0则0 | 或:有1则1,全0则0 ^ 异或:相同为0,不同为1 ~ 取反:~是一元运算符,用来对一 ...
- c语言中的结构体为值类型,当把一个结构体赋值给另一个结构体时,为值传递
#include <stdio.h> int main() { struct person { int age; }; }; //值传递,将p1中所有成员变量的值赋值个p2中对应的成员变量 ...
- C语言中的位运算的技巧
一.位运算实例 1.用一个表达式,判断一个数X是否是2的N次方(2,4,8,16.....),不可用循环语句. X:2,4,8,16转化成二进制是10,100,1000,10000.如果减1则变成01 ...
- 单片机C语言中标志位的经典应用
/* 本例程是C语言的位域操作示例 这里为什么位域结构体与联合体一起使用? -->因为这样定义后,即可以单独使用标志位 也可同时使用整个字节数据 主要应用:单片机C语言 好处:用标志位可以节省R ...
随机推荐
- html5 全屏滚动活动页学习
先看几个具体的实例: 1.腾讯娱乐:http://ent.qq.com/zt2014/qqent/h5.htm?from=groupmessage&isappinstalled=0 2.苏宁互 ...
- Spark Streaming揭秘 Day22 架构源码图解
Spark Streaming揭秘 Day22 架构源码图解 今天主要是通过图解的方式,对SparkStreaming的架构进行一下回顾. 下面这个是其官方标准的流程描述. SparkStreamin ...
- python中执行javascript代码
python中执行javascript代码: 1.安装相应的库,我使用的是PyV8 2.import PyV8 ctxt = PyV8.JSContext() ctxt.enter() ...
- Sharing
To store English words, one method is to use linked lists and store a word letter by letter. To save ...
- (转)Qt Model/View 学习笔记 (六)——在views中选择数据项
在views中选择数据项 概念 用于新的view类中的选择模型比Qt3中的模型有了很大的改进.它为基于model/view架构的选择提供了更为全面的描述.尽管对提供了的views来说,负责操纵选择的标 ...
- 【非原】c语言之声明和定义的区别
原创地址:http://www.cnblogs.com/haore147/p/3647466.html 什么是定义?什么是声明?它们有何区别? 举个例子: 1 2 A)int i; B)extern ...
- 【BZOJ 1040】 [ZJOI2008]骑士
Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火 ...
- eclipse *.vm 文件,语法高亮
eclipse *.vm 文件,语法高亮按如下方式不起作用,原因不明.设置文件打开时使用的编辑器General>>Editors>>File Associations 下述方试 ...
- BZOJ3404: [Usaco2009 Open]Cow Digit Game又见数字游戏
3404: [Usaco2009 Open]Cow Digit Game又见数字游戏 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 47 Solved ...
- 团体程序设计天梯赛-练习集L1-019. 谁先倒
L1-019. 谁先倒 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 划拳是古老中国酒文化的一个有趣的组成部分.酒桌上两人划拳 ...