1. 定义

浅拷贝(shallow copy):多个对象共用同一块资源,同一块资源释放多次,崩溃或者内存泄漏

深拷贝(deep copy):每个对象共同拥有自己的资源,必须显式提供拷贝构造函数和赋值运算符。

2. 示例

(书p355)

#include <iostream>
using namespace std;
//类声明
class String
{
private:
char* str;
int len;
static int num_strings;
public:
String(const char* s);
String();
~String();
friend std::ostream& operator<<(std::ostream& os, const String& s);
}; //不能在类声明中初始化静态成员变量
int String::num_strings = 0;
String::String(const char* s)
{
len = strlen(s);
str = new char[len + 1];
strcpy_s(str, strlen(s) + 1, s);
num_strings++;
cout << "num_strings:\"" << str << "\"object created\n";
} //类实现
String::String()
{
len = 4;
str = new char[len + 1];
strcpy_s(str, 4, "c++");
num_strings++;
cout << "num_strings:\"" << str << "\"object created\n";
} String::~String()
{
cout << "num_strings:\"" << str << "\"object deleted\n";
num_strings--;
cout << num_strings << " object left\n";
delete[] str;
} std::ostream& operator<<(std::ostream& os, const String& s)
{
os << s.str << ":" << int(s.str) << endl;
return os;
} //主函数
int main() {
{
String s1 = "aaaa";
cout << s1;
String s2 = s1;
cout << s2;
}
cout << "End of main()!\n";
return 0;
}

运行中断:

num_strings:"aaaa"object created
aaaa:16857352
aaaa:16857352
num_strings:"aaaa"object deleted
0 object left
num_strings:"葺葺葺葺葺葺葺葺?b@?"object deleted
-1 object left

默认的拷贝构造函数逐个复制非静态成员(浅拷贝),复制的是成员的值。

String s2 = s1;

相当于:

String s2;
s2.str = s1.str;
s2.len=s1.len;

其中,s2.str = s1.str复制的不是字符串,而是指向字符串的指针。也就是说,将s2初始化为是s1后,得到两个指针指向一个字符串。析构函数释放了s2.str指针指向的内存,因此在释放s2时,导致了不确定,可能有害的结果。

  解决这类设计中这种问题的方法是进行深拷贝(deep copy)。也就是说,拷贝构造函数应该复制字符串并将副本的地址赋给str成员,而不仅仅是复制字符串地址。这样每个对象都有自己的字符串,而不会试图去释放已经被释放的字符串。

可以定义一个显式拷贝构造函数以解决问题:

String::String(const String& st) {
len = st.len;
str = new char[len + 1];
strcpy_s(str, len+1, st.str);
num_strings++;
cout << "num_strings:\"" << str << "\"object created\n";
}

运行结果:

num_strings:"aaaa"object created
num_strings:"aaaa"object created
num_strings:"aaaa"object deleted
1 object left
num_strings:"aaaa"object deleted
0 object left
End of main()!

3. 总结

如果类中包含了使用new初始化的指针成员,应当定义一个拷贝构造函数,以复制指向的数据,而不是指针。

C++笔记(5)浅拷贝和深拷贝的更多相关文章

  1. Python day4_list的常见方法1_笔记(浅拷贝和深拷贝的简述)

    li=[1,2,3,'55dd'] li.clear()#清除列表内容 print(li) li.append(1)#追加 li.append(3) print(li) #拓展:直接赋值和copy和d ...

  2. 我的Python学习笔记(二):浅拷贝和深拷贝

    在Python中,对象赋值,拷贝(浅拷贝和深拷贝)之间是有差异的,我们通过下列代码来介绍其区别 一.对象赋值 对象赋值不会复制对象,它只会复制一个对象引用,不会开辟新的内存空间 如下例所示,将test ...

  3. 流畅的python学习笔记第八章:深拷贝,浅拷贝,可变参数

    首先来看赋值,浅拷贝,深拷贝. 一赋值: a=['word',2,3] b=a print id(a),id(b) print [id(x) for x in a] print [id(x) for ...

  4. Python3.5-20190504-自我笔记浅拷贝和深拷贝

    浅拷贝和深拷贝 (自己一直搞不懂的) 1.直接赋值(把一个变量直接赋值给另一个变量),他们指向同一个内存的数据(右边的图不知道怎么画,就直接截图过来了.将就看看) ------------- 2.使用 ...

  5. [编程基础] Python对象的浅拷贝与深拷贝笔记

    Python中的赋值语句不创建对象的副本,它们只将名称绑定到对象.对于不可变的对象,这通常没有什么区别.但是对于处理可变对象或可变对象的集合,您可能需要寻找一种方法来创建这些对象的"真实副本 ...

  6. c#中浅拷贝和深拷贝的理解

    c#中拷贝有浅拷贝和深拷贝之分. 例如对象A,其中有值类型字段和引用类型字段: 1.浅拷贝: 对于值类型字段,直接逐位复制到新拷贝的副本对象中,修改副本的字段的值,不会影响源对象中字段的值: 对于引用 ...

  7. C#浅拷贝与深拷贝区别

    也许会有人这样解释C# 中浅拷贝与深拷贝区别: 浅拷贝是对引用类型拷贝地址,对值类型直接进行拷贝. 不能说它完全错误,但至少还不够严谨.比如:string 类型咋说? 其实,我们可以通过实践来寻找答案 ...

  8. javascript 关于赋值、浅拷贝、深拷贝的个人理解

    关于赋值.浅拷贝.深拷贝,以前也思考良久,很多时候都以为记住了,但是,我太难了.今天我特地写下笔记,希望可以完全掌握这个东西,也希望可以帮助到任何想对学习这个东西的同学. 一.栈.堆.指针地址 栈内存 ...

  9. [转] js对象浅拷贝和深拷贝详解

    本文为大家分享了JavaScript对象的浅拷贝和深拷贝代码,供大家参考,具体内容如下 1.浅拷贝 拷贝就是把父对像的属性,全部拷贝给子对象. 下面这个函数,就是在做拷贝: var Chinese = ...

  10. 【转】Python中的赋值、浅拷贝、深拷贝介绍

    这篇文章主要介绍了Python中的赋值.浅拷贝.深拷贝介绍,Python中也分为简单赋值.浅拷贝.深拷贝这几种"拷贝"方式,需要的朋友可以参考下   和很多语言一样,Python中 ...

随机推荐

  1. maven 创建spring boot 需要的配置[一]

    前言 之所以写这个是因为现在官方推荐云创建: 所以标注一下maven project,创建后,如何导入spring boot. 正文 1.步骤一 在pom.xml 中加入: <dependenc ...

  2. xml转voc,voc转coco,coco转yolo,coco划分,coco检查,yolo检查,coco可视化

    平常用coco格式的数据集比较多,所有这里整合一下数据集相关的常用的脚本. pycocotools安装 这个非常重要,因为处理coco数据集时,用pycocotools包非常方便. 自行搜索一下怎么安 ...

  3. threading的定时器模块,python,每间隔一段时间执行一次任务

    工作中常有一些定时任务要处理,比如使用百度的接口,它的access_token是一个更新一次的,每次使用时总是请求会很慢,所以我们把它保存起来,用定时器模块,定时在过期之前请求一次,或者定时数据同步, ...

  4. Oracle 查询超级慢之buffer sort

    查询超级慢之buffer sort 在视图中增加了一个临时表作为一个数据源进行id和名称的转换,没加的时候一秒不到,加了以后14秒,感觉有点问题,于是打开了解释计划看了下,发现这个buffer sor ...

  5. 新零售标杆 SKG 全面拥抱 Serverless,实现敏捷交付

    简介: SKG CTO 王焱:以前需要 60 个人干的活,用 SAE 和大禹后 15 个人就可以! 作者:陈列昂.昕辰.龙琛.黛忻 项目背景   SKG 公司是一家专注于高端健康产品的研发.设计与制造 ...

  6. Java Agent 踩坑之 appendToSystemClassLoaderSearch 问题

    简介: 从 Java Agent 报错开始,到 JVM 原理,到 glibc 线程安全,再到 pthread tls,逐步探究 Java Agent 诡异报错. 作者:鲁严波   从 Java Age ...

  7. 璀璨智行:V2X车路协同智慧交通

    ​V2X车用无线通信技术是指车对外界的信息交换,作为未来智能交通运输系统的关键技术,璀璨智行潜心研究V2X技术,致力于V2X车路协同的落地,在智慧交通领域做出了卓越的贡献. 创业机会点 魏军博表示:& ...

  8. 如何在零停机的情况下迁移 Kubernetes 集群

    ​简介:本文将通过集群迁移的需求.场景以及实践方式,介绍如何基于阿里云容器服务 ACK,在零停机的情况下迁移 Kubernetes 集群. 作者:顾静(子白)|阿里云高级研发工程师:谢瑶瑶(初扬)|阿 ...

  9. HMS数据库设置和优化

    简介:Hive Metastore (HMS) 是一种服务,用于在后端 RDBMS(例如 MySQL 或 PostgreSQL)中存储与 Apache Hive 和其他服务相关的元数据.本文主要分享H ...

  10. CSS3 transition动画、transform变换、animation动画

    一.CSS3 transition动画 transition可以实现动态效果,实际上是一定时间之内,一组css属性变换到另一组属性的动画展示过程. 属性参数: 1.transition-propert ...