C++的浅拷贝与深拷贝

article/2025/9/17 4:27:01

目录

前言

一、区别

二、浅拷贝

1.简单描述

2.代码实例

三.深拷贝

1.简单描述

2.代码实例

 四.完整代码

五.运行结果

总结


前言

C++中有两种拷贝:深拷贝和浅拷贝

要是想要运用好拷贝函数就必须清楚深拷贝与浅拷贝的区别

一、区别

1  在未定义拷贝构造函数的情况下,系统会调用默认的拷贝函数——即浅拷贝(不用自己构造),它能够完成成员的简单的值的拷贝一一复制。当数据成员中没有指针时,浅拷贝是可行的;但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址(同一个堆区),当对象快结束时,会调用两次析构函数(析构函数也无需自己构造,但想要知道析构函数的工作可以自己构造析构函数用输出来记录),而导致指针悬挂现象,所以,此时,必须采用深拷贝。
2 深拷贝与浅拷贝的区别就在于深拷贝会在堆内存中另外申请空间来储存数据(新的堆区空间进行拷贝),从而也就解决了指针悬挂的问题。简而言之,当数据成员中有指针时,必须要用深拷贝。

二、浅拷贝

1.简单描述

       同一类型的对象之间可以赋值,使得两个对象的成员变量的值相同,两个对象仍然是独立的两个对象,这种情况被称为浅拷贝.

        一般情况下,浅拷贝没有任何副作用,但是当类中有指针,并且指针指向动态分配的内存空间,析构函数做了动态内存释放的处理,会导致内存问题。

2.代码实例

无自己构造的拷贝函数即无深拷贝构造函数:

析构函数是用来检验浅拷贝不能简单拷贝指针指向的堆区空间内容。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;
class Person
{public:Person(){}//初始化属性Person(const char* name, int age){Name = (char*)malloc(strlen(name) + 1);} //拷贝构造 系统会提供默认拷贝构造,而且是简单的值的拷贝即浅拷贝//析构调用~Person(){cout << "析构函数的调用" << endl;if (Name != NULL){free(Name);Name = NULL;}}//姓名char* Name;//年龄int Age;};
void test01()
{Person p1("光头强", 10);Person p2(p1);//调用拷贝构造
}int main(void)
{test01();system("pause");return 0;
}


  运行结果会崩掉,原因就是:系统会提供一个默认的简单值的拷贝即浅拷贝,实例代码中的p1.Age会被正常拷贝(浅拷贝),而指针p1对象中的*Name和(浅)拷贝p1后的p2中的*Name指向同一个堆区空间,因此析构函数会析构两回这个同一堆区空间而崩溃。p1对象中的Age进行拷贝是浅拷贝,p1对象中的指针*Name进行拷贝是深拷贝。
见下图:(指针指向同一堆区空间)
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑

三.深拷贝

1.简单描述

       当类中有指针,并且此指针有动态分配空间,析构函数做了释放处理,往往需要自定义拷贝构造函数,自行给指针动态分配空间,深拷贝。

2.代码实例

上述示例代码加上拷贝构造函数即可实现深拷贝:

//增加拷贝构造函数  深拷贝Person(const Person& p){Age = p.Age;Name = (char*)malloc(strlen(p.Name) + 1);//新建一个堆区空间strcpy(Name, p.Name);}

见下图:(深拷贝新建了一个堆区空间)

运行结果是进行两次析构


 四.完整代码

 

深拷贝与浅拷贝的实现

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>using namespace std;
class Person
{public:Person(){}//初始化属性Person(const char* name, int age){Name = (char*)malloc(strlen(name) + 1);} //拷贝构造 系统会提供默认拷贝构造,而且是简单的值的拷贝即浅拷贝//增加拷贝构造函数Person(const Person& p){Age = p.Age;Name = (char*)malloc(strlen(p.Name) + 1);strcpy(Name, p.Name);}//析构调用~Person(){cout << "析构函数的调用" << endl;if (Name != NULL){free(Name);Name = NULL;}}//姓名char* Name;//年龄int Age;};
void test01()
{Person p1("光头强", 10);Person p2(p1);//调用拷贝构造
}int main(void)
{test01();system("pause");return 0;
}

五.运行结果

 

总结

深拷贝和浅拷贝的区别是在对象状态中包含其它对象的引用的时候,深拷贝的实现需要构造拷贝函数新建一个堆区空间在进行拷贝,浅拷贝直接拷贝即可(简单的值的拷贝)。


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

相关文章

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

一、概念介绍 拷贝构造&#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;称为栈顶端指标&…

栈和队列简介

栈和队列简介 栈和队列是两种常用的数据结构&#xff0c;它们的数据是按线性结构存储的&#xff0c;因此&#xff0c;栈和队列也属于线性表。 栈和队列的数据可以存储在一个顺序表里&#xff0c;也可以存储在一个链表里&#xff0c;只要满足线性存储结构就行。只对数据的线性…

栈和队列基本操作

栈和队列 一、栈栈是什么栈的实现栈的基本操作栈类型的定义初始化栈检查栈是否为满入栈出栈获取栈顶元素检测栈是否为空测试函数 完整代码Stack.hStack.cmain.c 二、队列队列是什么队列的实现队列类型的定义申请一个节点初始化队列队尾入队列队头出队列获取队列头部元素获取队列…

C#队列和栈的使用

一、队列 队列是其元素以先进先出&#xff08;Firstin,Firstout,FIFO&#xff09;的方式来处理的集合。先放入队列中的元素会先读取。队列使用System.Collections.Generic命名空间中的泛型类Queue<T>实现。 队列的成员 Count&#xff1a;Count属性返回队列中元素个数。…

栈和队列经典面试题

目录 1、括号匹配问题 2、用队列实现栈 3、用栈实现队列 4、设计循环队列 1、括号匹配问题 链接直达&#xff1a; 有效的括号 题目&#xff1a; 思路&#xff1a; 做题前&#xff0c;得先明确解题方案是啥&#xff0c;此题用栈的思想去解决是较为方便的&#xff0c;栈明确指…

栈stack和队列

栈和队列 一 栈和队列二 栈三.队列 一 栈和队列 栈和队列是两种重要的线性结构。从数据结构来看&#xff0c;栈和队列也是线性表&#xff0c;其特殊性在于栈和队列的基本操作是线性表操作的子集&#xff08;也具有顺序结构和链式结构&#xff09;&#xff0c;它们是操作受限的…

链表,队列和栈的区别

链表&#xff0c;队列和栈都是数据结构的一种。Sartaj Sahni 在他的《数据结构、算法与应用》一书中称&#xff1a;“数据结构是数据对象&#xff0c;以及存在于该对象的实例和组成实例的数据元素之间的各种联系。这些联系可以通过定义相关的函数来给出。”他将数据对象&#x…

栈与队列的定义与区别

1、栈 首先&#xff0c;普通的线性表实现是有两个端口可以访问的&#xff0c;但是如果作为栈就要封闭一端&#xff0c;只能访问另一端。这当然不是自讨苦吃&#xff0c;栈是一种抽象数据结构&#xff0c;是对现实世界对象的模拟。比如&#xff0c;自助餐厅中的一叠盘子&#x…

java 队列和栈的区别

栈和队列的区别 &#xff08;1&#xff09;数据插入删除 栈是一种特殊的线性表&#xff0c;他只能在一段进行插入和删除操作&#xff0c;就好像是一个井一样。进行数据插入和删除就类似于井口&#xff0c;称为栈定。而井也是有底部的&#xff0c;栈无法进行插入删除操作的这一…

监督学习和无监督学习的区别(机器学习)

机器学习主要分为两类 监督学习无监督学习 两者的区别主要是是否需要人工参与数据结果的标注 监督学习&#xff1a;教计算机如何去完成预测任务&#xff08;有反馈&#xff09;&#xff0c;预先给一定数据量的输入和对应的结果即训练集&#xff0c;建模拟合&#xff0c;最后让…