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 ...
随机推荐
- 四个基数任意次数组合相加得到一个数N,求所有可能组合
#include <iostream> #include <vector> usingnamespace std; vector<int> vec; constin ...
- windows 与fedora时间差
windows 默认BIOS时间当前时间UTC+时区, 按北京时间时区,就是要加8个小时. Linux默认BIOS时间是UTC时间,所以同一机子上装WINDOWS与LINUX时间上会差8个小时.这问题 ...
- Oracle分析函数 — sum, rollup, cube, grouping用法
本文通过例子展示sum, rollup, cube, grouping的用法. //首先建score表 create table score( class nvarchar2(20), course ...
- 微信支付配置信息,JSAPI接口,H5调用微信js接口支付,微信公众号支付
微信支付已经做完了,没接触过微信的我,经历了非常艰难的3天,才把微信支付给做出来,对于专业的人来说,估计就是一小时就搞定的事情了,虽然说做了很长时间,但是确实也学到东西了,也收获了不少,下面跟大家分享 ...
- SecureCRT上传bash: rz: command not found(转载)
转载自:http://blog.csdn.net/zhangdaiscott/article/details/18141017 -bash: rz: command not found rz命令没找到 ...
- Weblogic12c安装与配置详解
Weblogic是什么Weblogic的安装Weblogic创建域Weblogic管理域Weblogic的应用Weblogic是什么 Weblogic这是我入职以后第一次接触到的词汇,我很陌生,就从我 ...
- python学习笔记6(字典)
映射:键值对的关系,键(key)映射值(value) 字典是Python唯一的映射类型 >>> phonebook = {'} >>> phonebook {'} ...
- android/IOS各平台分享链接/跳转链接配置说明(备用)
Android: [Java] 纯文本查看 复制代码 ? 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 微信/朋友圈 //设置 ...
- mybatis 中mapper 的namespace有什么用
原文:http://zhidao.baidu.com/link?url=ovFuTn7-02s7Qd40BOnwHImuPxNg8tXJF3nrx1SSngNY5e0CaSP1E4C9E5J6Xv5f ...
- SAML - SSO(转)
http://baike.baidu.com/view/758527.htm?fr=aladdin SAML即安全断言标记语言,英文全称是Security Assertion Markup Langu ...