c++深拷贝与浅拷贝

article/2025/9/17 3:49:10

浅拷贝:简单的赋值拷贝操作(这个是系统默认提供的)

深拷贝:在堆区重新释放空间,进行拷贝操作(要自己写的)

简单来说,只要类属性里有指针等就必须利用深拷贝操作

为便于深刻理解,先看一个实例:

#include<iostream>
using namespace std;
class Person                                  ******Person类分隔符*******
{
public:Person(){cout<<"默认构造函数的调用\n";}Person(int age){cout<<"有参构造函数的调用\n";m_age=age;}	~Person(){cout<<"析构函数的调用\n";}int m_age;
};                                           ******Person类分隔符*******
int main()
{Person a(10);Person b(a);cout<<"a的年龄为:"<<a.m_age<<endl;cout<<"b的年龄为:"<<b.m_age<<endl; 
}

运行结果:

运行结果显然没有问题,我们在初始化类b的时候,系统调用了默认拷贝构造函数,把a中的值传递给了b;下面,我们增加类Person的一个指针属性m_height,并且把身高属性放置到堆区:

tip:堆区由程序员手动开创与释放,new出来的数据就位于堆区

#include<iostream>
using namespace std;
class Person                                 ******Person类分隔符*******
{
public:Person(){cout<<"默认构造函数的调用\n";}Person(int age,int height){cout<<"有参构造函数的调用\n";m_age=age;m_height=new int(height);    //**}	~Person(){cout<<"析构函数的调用\n";}int m_age;int* m_height;
};                                           ******Person类分隔符*******
int main()
{Person a(19,170);Person b(a);cout<<"a的年龄为:"<<a.m_age<<"  a的身高为:"<<*a.m_height<<endl;cout<<"b的年龄为:"<<b.m_age<<"  b的身高为:"<<*b.m_height<<endl; 
}

运行结果为:

 运行结果看起来没问题,但是代码实际上是不规范的;堆区的数据需要程序员手动开创与释放,需要用到析构函数,我们进行析构代码的完善:

~Person(){//析构代码,将堆区开辟的数据释放干净if(m_height!=NULL){delete m_height;m_height=NULL;    //防止指针滞空变成野指针}cout<<"析构函数的调用\n";}

但当继续运行程序的时候会发现代码已经崩了(部分编译器现象不明显,如Dev,这里不再截图),什么原因导致的?我们分析一下:

 二次释放同一块内存会被编译器视为非法操作;可知,浅拷贝带来的问题就是堆区的内存被重复释放。解决这个问题就需要利用深拷贝,具体做法便是重新开辟一个内存空间存放数据,利用深拷贝构造函数使b的指针指向新开辟的空间,这样,a与b各指向一块堆区的数据,两块空间存放的数据是一样的,这样就在拷贝的同时避免了对同一空间的重复释放问题。

 具体代码实现如下:

#include<iostream>
using namespace std;
class Person                                             *****类Person***** 
{
public:Person(){cout<<"默认构造函数的调用\n";}Person(int age,int height){cout<<"有参构造函数的调用\n";m_age=age;m_height=new int(height);}	Person(const Person& p){cout<<"拷贝构造函数的调用"<<endl;m_age=p.m_age;m_height=new int(*p.m_height);//                <-深拷贝操作 //编译器提供的拷贝函数是:m_height=p.m_height;     <-浅拷贝//由此可见浅拷贝中a,b指向的是同一块内存}~Person(){if(m_height!=NULL){delete m_height;m_height=NULL;    //防止指针滞空变成野指针}cout<<"析构函数的调用\n";}int m_age;int* m_height;
};                                                       *****类Person*****
int main()
{Person a(19,170);Person b(a);cout<<"a的年龄为:"<<a.m_age<<"  a的身高为:"<<*a.m_height<<endl;cout<<"b的年龄为:"<<b.m_age<<"  b的身高为:"<<*b.m_height<<endl; 
}

运行结果为:

———— ———— ———— —————分割线———— ———— ———— ———— ————

下面附两张截图:

浅拷贝时两个对象height属性的地址:

 深拷贝时两个对象height的地址:

如果对你有用,希望优秀的你能给作者一个小小的赞和收藏[emoji]


http://chatgpt.dhexx.cn/article/LE3YQhpH.shtml

相关文章

实现深拷贝与浅拷贝的方法

深拷贝与浅拷贝概念&#xff1a; 深浅拷贝出现的前提&#xff1a; 应用类型的数据&#xff08;对象和数组&#xff09; 深拷贝就是把目标对象里面的数据一个一个都复制下来&#xff0c;创建出一个一模一样的&#xff0c;存放地址不一样&#xff0c;互不影响。就像真假美猴王。改…

深拷贝和浅拷贝的区别及实现方法

文章目录 一、引言二、浅拷贝1.Object.assign()2.concat()3.扩展运算符 三、深拷贝1. 利用json数据和json字符串之间的转换2.$.extend()3. 递归 查阅多篇文章后&#xff0c;自己归纳总结对深拷贝和浅拷贝的理解&#xff0c;不足之处&#xff0c;还望多多指导 一、引言 基本数据…

深拷贝与浅拷贝的区别

深拷贝与浅拷贝是针对对象属性为对象的&#xff0c;因为基本数据类型在进行赋值操作时&#xff08;也就是深拷贝&#xff08;值拷贝&#xff09;&#xff09;&#xff0c;是直接将值赋给了新的变量&#xff0c;也就是该变量是原变量的一个副本&#xff0c;这时&#xff0c;你修…

深拷贝和浅拷贝的区别是什么?

深拷贝和浅拷贝的区别是什么? 1、浅拷贝 (1)、定义 被复制对象的所有变量都含有与原来的对象相同的值&#xff0c;而所有的对其他对象的引用仍然指向原来的对象。即对象的浅拷贝会对“主"对象进行拷贝&#xff0c;但不会复制主对象里面的对象。"里面的对象”会在…

深拷贝和浅拷贝常见的实现方式

浅拷贝的实现方式 1. Object.assign()方法 assign()方法是把任意多个的源对象自身的可枚举属性拷贝给目标对象&#xff0c;然后返回目标对象。但是他的拷贝方式不是固定的&#xff0c;看下面的代码演示&#xff1a; let obj {username: kobe}; let obj2 Object.assign({},o…

什么是深拷贝和浅拷贝?以及怎么实现深拷贝和浅拷贝?

拷贝浅是创建一个新对象&#xff0c;这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型&#xff0c;拷贝的就是基本类型的值&#xff0c;如果属性是引用类型&#xff0c;拷贝的就是内存地址&#xff0c;所以如果其中一个对象改变了这个地址&#xff0c;就会影响到…

Java的深拷贝与浅拷贝的区别

1.二者的区别 浅拷贝&#xff1a;在拷贝一个对象时&#xff0c;对对象的基本数据类型的成员变量进行拷贝&#xff0c;但对引用类型的成员变量只进行引用的传递&#xff0c;并没有创建一个新的对象&#xff0c;当对引用类型的内容修改会影响被拷贝的对象。 深拷贝&#xff1a;在…

深拷贝和浅拷贝的区别(必须掌握)

前言&#xff1a; 在面试中&#xff0c;你必须要知道的一个知识点&#xff0c;那就是浅拷贝和深拷贝&#xff0c;那么就必须知道基本数据类型和引用类型&#xff0c;其实深拷贝和浅拷贝的主要区别就是其在内存中的存储类型不同。 网片来自网络&#xff08;侵删&#xff09; …

C++的浅拷贝与深拷贝

目录 前言 一、区别 二、浅拷贝 1.简单描述 2.代码实例 三.深拷贝 1.简单描述 2.代码实例 四.完整代码 五.运行结果 总结 前言 C中有两种拷贝&#xff1a;深拷贝和浅拷贝 要是想要运用好拷贝函数就必须清楚深拷贝与浅拷贝的区别 一、区别 1 在未定义拷贝构造函数…

拷贝构造(深拷贝、浅拷贝)

一、概念介绍 拷贝构造&#xff1a;拷贝构造函数&#xff0c;又称构造函数&#xff0c;是一种特殊的构造函数&#xff0c;它由编译器调用来完成一些基于同一类的其他对象的构造及初始化。 其唯一的形参必须是引用&#xff0c;但并不限制为const&#xff0c;一般普遍的会加上c…

C++——深拷贝和浅拷贝

1.浅拷贝与深拷贝的区别 浅拷贝&#xff08;默认拷贝函数&#xff09;&#xff1a;将原对象或原数组的引用直接赋给新对象&#xff0c;新数组&#xff0c;新对象/新数组只是原对象的一个引用。 深拷贝&#xff1a;创建一个新的对象和数组&#xff0c;将原对象的各项属性的“值”…

深拷贝和浅拷贝的区别和与原理

一、基本类型和引用类型 string,number,boolean,null,undefined,symbolFunction,Array,Object 基本类型是按值访问的&#xff0c;引用类型是按引用访问 基本类型和引用类型也有人叫原始类型和对象类型&#xff0c;拥有方法的类型和不能拥有方法的类型&#xff0c;可变类型和不…

浅拷贝、深拷贝

深拷贝和浅拷贝 这两个概念是在项目中比较常见的&#xff0c;在很多时候&#xff0c;都会遇到拷贝的问题&#xff0c;我们总是需要将一个对象赋值到另一个对象上&#xff0c;但可能会在改变新赋值对象的时候&#xff0c;忽略掉我是否之后还需要用到原来的对象&#xff0c;那么就…

深拷贝和浅拷贝(copy和deepcopy)详解

深拷贝和浅拷贝&#xff08;copy和deepcopy&#xff09;详解 详细解释存储方式列表的增删改列表修改已有值列表新增一个值列表整体重新赋值 copy与deepcopy的区别不可变类型可变类型 浅拷贝指的是创建一个新对象&#xff0c;其中包含原始对象的引用&#xff08;指针&#xff09…

浅拷贝和深拷贝的区别?

创建Java对象的方式包括new、反射、反序列化、拷贝&#xff0c;那么什么是拷贝呢&#xff1f;浅拷贝和深拷贝又有什么区别呢&#xff1f; 什么是拷贝 拷贝就是为了复用原对象的部分或全部数据&#xff0c;在原对象的基础上通过复制的方式创建一个新的对象。 Object类中有nati…

深拷贝和浅拷贝的区别

首先&#xff0c;明确一点深拷贝和浅拷贝是针对对象属性为对象的&#xff0c;因为基本数据类型在进行赋值操作时&#xff08;也就是拷贝&#xff09;是直接将值赋给了新的变量&#xff0c;也就是该变量是原变量的一个副本&#xff0c;这个时候你修改两者中的任何一个的值都不会…

浅拷贝与深拷贝的区别

浅拷贝与深拷贝 一、数据类型 数据分为基本数据类型(String, Number, Boolean, Null, Undefined&#xff0c;Symbol)和对象数据类型。 基本数据类型的特点&#xff1a;直接存储在栈(stack)中的数据 引用数据类型的特点&#xff1a;存储的是该对象在栈中引用&#xff0c;真实的…

堆、栈和队列

1. 堆 堆是在程序运行时&#xff0c;而不是在程序编译时&#xff0c;申请某个大小的内存空间。即动态分配内存&#xff0c;对其访问和对一般内存的访问没有区别。堆是指程序运行时申请的动态内存&#xff0c;而栈只是指一种使用堆的方法(即先进后出)。 2. 栈&#xff08;stack&…

堆、栈和队列的区别

目录 数据结构中的堆、栈和队列 内存申请中的堆和栈 一个C/C程序占用的内存如下&#xff1a; 申请内存后的响应 申请大小的限制 申请效率的比较 堆和栈中的存储内容 数据结构中的堆、栈和队列 堆&#xff1a;堆是一种经过排序的树形数据结构&#xff0c;每个结点都有…

栈和队列

文章目录 栈栈操作队列队列操作双端队列双端队列操作 栈 栈&#xff08;stack&#xff09;&#xff0c;有些地方称为堆栈&#xff0c;是一种容器&#xff0c;可存入数据元素、访问元素、删除元素&#xff0c;它的特点在于只能允许在容器的一端&#xff08;称为栈顶端指标&…