c++深拷贝和浅拷贝[通俗易懂]

c++深拷贝和浅拷贝[通俗易懂]C++中类的拷贝有两种:深拷贝,浅拷贝当出现类的等号赋值时,会调用拷贝函数在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有指针时,浅拷贝是可行的。但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象。所以,这时,必须采用深拷贝。深拷贝与浅拷贝

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

C++中类的拷贝有两种:深拷贝,浅拷贝:当出现类的等号赋值时,即会调用拷贝函数
一:两个的区别
1  在未定义显示拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝,它能够完成成员的一一复制。当数据成员中没有指针时,浅拷贝是可行的;但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,而导致指针悬挂现象,所以,此时,必须采用深拷贝。
2 深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据,从而也就解决了指针悬挂的问题。简而言之,当数据成员中有指针时,必须要用深拷贝。
二  带实例的解释
c++默认的拷贝构造函数是浅拷贝
浅拷贝就是对象的数据成员之间的简单赋值,如你设计了一个没有类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如:
class A 
{ 
	public: 
	A(int _data) : data(_data){} 
	A(){}
	private: 
	int data;
 };
int main() 
{ 
	A a(5), b = a; // 仅仅是数据成员之间的赋值 
}
这一句b = a;就是浅拷贝,执行完这句后b.data = 5;
如果对象中没有其他的资源(如:堆,文件,系统资源等),则深拷贝和浅拷贝没有什么区别,
但当对象中有这些资源时,例子:
class A 
{ 
	public: 
	A(int _size) : size(_size)
	{
		data = new int[size];
	} // 假如其中有一段动态分配的内存 
	A(){};
	 ~A()
	{
		delete [] data;
	} // 析构时释放资源
	private: 
	int* data;
	int size; 
}
int main() 
{ 
	A a(5), b = a; // 注意这一句 
}
这里的b = a会造成未定义行为,因为类A中的复制构造函数是编译器生成的,所以b = a执行的是一个浅拷贝过程。我说过浅拷贝是对象数据之间的简单赋值,比如:
b.size = a.size;
b.data = a.data; // Oops!
这里b的指针data和a的指针指向了堆上的同一块内存,a和b析构时,b先把其data指向的动态分配的内存释放了一次,而后a析构时又将这块已经被释放过的内存再释放一次。对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃所以这里就需要深拷贝来解决这个问题,深拷贝指的就是当拷贝对象中有对其他资源(如堆、文件、系统等)的引用时(引用可以是指针或引用)时,对象的另开辟一块新的资源,而不再对拷贝对象中有对其他资源的引用的指针或引用进行单纯的赋值。如:
class A 
{ 
	public: 
	A(int _size) : size(_size)
	{
		data = new int[size];
	} // 假如其中有一段动态分配的内存 
	A(){};
	A(const A& _A) : size(_A.size)
	{
		data = new int[size];
	} // 深拷贝 
	~A()
	{
		delete [] data;
	} // 析构时释放资源
	private: 
	int* data; 
 	int size;
 }
int main() 
{ 
	A a(5), b = a; // 这次就没问题了 
}
总结:深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,当拷贝一个对象时,如果需要拷贝这个对象引用的对象,则是深拷贝,否则是浅拷贝。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/187091.html原文链接:https://javaforall.net

(0)
上一篇 2022年10月1日 下午3:36
下一篇 2022年10月1日 下午3:46


相关推荐

  • update 数据。表之间关联 赋值

    update 数据。表之间关联 赋值

    2022年3月7日
    40
  • 3D打印上位机软件

    3D打印上位机软件本文将主要介绍在3D打印中常见的3D打印上位机软件,这类3D软件将为用户提供较大的帮助,通过对这类软件的分类,用户可以选择使用最适合自己的软件。没有恐惧,我们已经回答了所有这些问题,以及熟练程度的细节和可以下载的细节。最重要的是,他们大多数是完全免费和开源的。我们错过了您最喜爱的3D打印软件吗?让我们在评论中知道,我们会在将来的更新中添加它们。1、curaCura可以被称…

    2022年5月31日
    70
  • git合并分支代码

    git合并分支代码目录 1 git 合并分支代码 2 gitfetch gitpull gitmerge 原理 引申 一 git 合并分支代码举例 本地分支 master 远程目标分支 dev 合并 将远程 origin 仓库的 dev 分支合并到本地的 master 分支 git 合并分支代码一般有如下两种方式第一种方式 gitfetchorig fetc

    2026年3月17日
    2
  • 两个一般性矩阵互相相似的条件

    两个一般性矩阵互相相似的条件在复习的时候突然遇到一个问题 两个普通矩阵怎么判定相似 之前遇到的题目里面都是使用相似对角化的方法 这里就不在仔细介绍 总结就是如果当前矩阵的每一个特征值的几何重数和代数重数均相等 则可以相似于一个对角阵 如果两个矩阵相似于同一个对角阵 则这两个矩阵相似 A BA sim Lambda simBA B 这样就要求 A 和 B 拥有同样的特征值 并且每一个特征值的几何重数等于代数重数 并且两矩阵对应特征值的几何重数也要相等 这样先然不是最简的条件 经过网上查询 发现两个矩阵相似不一定同时相似

    2025年8月5日
    5
  • 月之暗面发布并开源Kimi K2模型

    月之暗面发布并开源Kimi K2模型

    2026年3月12日
    2
  • 国内如何注册Claude账号?最新详细教程

    国内如何注册Claude账号?最新详细教程

    2026年3月16日
    1

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号