C++ 学习之深拷贝 和 浅拷贝

这篇具有很好参考价值的文章主要介绍了C++ 学习之深拷贝 和 浅拷贝。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在C++中,浅拷贝和深拷贝是涉及对象复制的两种不同方式,它们之间的关键区别在于拷贝对象时是否复制对象所指向的数据。

正文

浅拷贝(Shallow Copy)

  • 浅拷贝只复制对象本身,而不复制对象所指向的数据。
  • 当你使用浅拷贝创建一个新对象时,它将与原始对象共享相同的数据。这意味着如果一个对象修改了共享数据,另一个对象也会受到影响,因为它们指向相同的内存位置。
  • 浅拷贝通常是通过默认的复制构造函数或赋值操作符来执行的。

深拷贝(Deep Copy)

  • 深拷贝复制对象本身以及对象所指向的数据。它创建了一个新的独立副本,而不是与原始对象共享数据。
  • 深拷贝确保原始对象和新对象是完全独立的,修改一个对象不会影响另一个对象。
  • 深拷贝通常需要自定义复制构造函数和赋值操作符,以确保数据的完全复制。

分析代码

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
// 浅拷贝:简单的赋值拷贝操作

// 深拷贝:在堆区重新申请空间,进行拷贝操作

class Person
{
public:
	Person()
	{
		cout << "Person 的默认构造函数调用 " << endl;

	}
	Person(int age,int height)
	{
		m_age = age;
		m_height = new int(height);
		cout << "Person 的 有参构造函数调用  " << endl;
	}

	~Person()  // 析构函数,将堆区开辟的数据释放操作
	{
		
			delete m_height;
			m_height = NULL;
		
		cout << "Person 的析构函数的调用 " << endl;
	}
	int m_age;
	int* m_height;
};

void test()
{
	Person p1(18, 160);

	cout << "p1的年龄为: " << p1.m_age << " 身高为 " << *p1.m_height << endl;

	Person p2(p1);

	cout << "p2的年龄为: " << p2.m_age << " 身高为 " << *p2.m_height << endl;
}

int main()
{
	test();
}

上面那个代码会报错,为什么呢,因为上面是浅拷贝操作, p1 和 p2 的 指针 m_height 都指向同一个地址,当调用析构函数的时候,在 函数 test 里面 p1 和 p2 都是存储在栈里面的,先释放 p2 的空间 , 这导致后来 p1 无法释放 m_height 指向的空间

C++ 学习之深拷贝 和 浅拷贝,c++,c++,学习,开发语言
会产生上面的报错

我们可以通过 将

		delete m_height;
		m_height = NULL;

改成

if (!m_height)
		{
			delete m_height;
			m_height = NULL;
		}

浅拷贝带来的问题就是 堆区内存的重复释放带来的问题

利用深拷贝操作

我们可以写 拷贝函数 ,不使用默认的构造函数来实现深拷贝

Person(const Person& p)
	{
		cout << " Person 的 拷贝函数的调用 " << endl;
		m_age = p.m_age;
	//	m_height = p.m_height;  编译器默认实现的就是这行代码

		// 自己实现深拷贝操作

		m_height = new int(*p.m_height);
	}

我们来看看具体的代码实现

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
// 浅拷贝:简单的赋值拷贝操作

// 深拷贝:在堆区重新申请空间,进行拷贝操作

class Person
{
public:
	Person()
	{
		cout << "Person 的默认构造函数调用 " << endl;

	}
	Person(int age,int height)
	{
		m_age = age;
		m_height = new int(height);
		cout << "Person 的 有参构造函数调用  " << endl;
	}
	// 自己构造拷贝函数,解决浅拷贝带来的问题
	Person(const Person& p)
	{
		cout << " Person 的 拷贝函数的调用 " << endl;
		m_age = p.m_age;
	//	m_height = p.m_height;  编译器默认实现的就是这行代码

		// 自己实现深拷贝操作

		m_height = new int(*p.m_height);
	}

	~Person()  // 析构函数,将堆区开辟的数据释放操作
	{
	
		delete m_height;
		m_height = NULL;
		cout << "Person 的析构函数的调用 " << endl;
	}
	int m_age;
	int* m_height;
};

void test()
{
	Person p1(18, 160);

	cout << "p1的年龄为: " << p1.m_age << " 身高为 " << *p1.m_height << endl;

	Person p2(p1);

	cout << "p2的年龄为: " << p2.m_age << " 身高为 " << *p2.m_height << endl;
}

int main()
{
	test();
}

这样 p1 和 p2 的 m_height 指向的堆的内存地址就不一样了,代码就不会报错了文章来源地址https://www.toymoban.com/news/detail-707263.html

到了这里,关于C++ 学习之深拷贝 和 浅拷贝的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • NRCE 二级C语言开发环境:Microsoft Visual C++ 2010 学习版下载

    Microsoft Visual C++ 2010 学习版 2022版考纲 网盘链接:点击下载 提取码:siyy 网盘地址下载太慢可以到:官网下载 下载完成后,是一个iso镜像文件,点击上方装载。 装载完成后,可以看到计算机处有个无穷图标的DVD驱动器 现在就可以去到你安装磁盘目录下的IDE目录(星号中间的

    2024年02月11日
    浏览(43)
  • C++ 学习 ::【基础篇:16】:C++ 类的基本成员函数:拷贝构造函数(认识、特征、注意点及典型使用场景)及其基本写法与调用

    本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段: 基础篇、STL 篇、高阶数据结构与算法篇 ,相关重点内容如下: 基础篇 : 类与对象 (涉及C++的三大特性等); STL 篇 : 学习使用 C++ 提供的 STL 相关库 ; 高阶数据结构与算

    2024年02月08日
    浏览(35)
  • 【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之数码管静态显示(四)

      本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGL22G开发平台(盘古22K) 一:盘古22K开发板(紫光同创PGL22G开发平台)简介 盘古22K开发板是基于紫光同创Logos系列PGL22G芯片设计的一款FPGA开发板

    2024年02月10日
    浏览(33)
  • C++深拷贝与浅拷贝

    默认提供的拷贝构造就是浅拷贝,如果拷贝的对象中含有成员指针变量指向堆区中的内存空间,那么就会出现两个对象中的成员指针变量指向同一块堆区空间,当方法执行结束后,对象就会被释放,调用析构函数(析构函数中存在释放在堆区开辟的内存空间),就会存在一块内

    2023年04月25日
    浏览(26)
  • 【两周学会FPGA】从0到1学习紫光同创FPGA开发|盘古PGL22G开发板学习之DDR3 IP简单读写测试(六)

    本原创教程由深圳市小眼睛科技有限公司创作,版权归本公司所有,如需转载,需授权并注明出处 适用于板卡型号: 紫光同创PGL22G开发平台(盘古22K) 一:盘古22K开发板(紫光同创PGL22G开发平台)简介 盘古22K开发板是基于紫光同创Logos系列PGL22G芯片设计的一款FPGA开发板,全

    2024年01月23日
    浏览(55)
  • C++:构造方法(函数);拷贝(复制)构造函数:浅拷贝、深拷贝;析构函数。

    1.构造方法(函数) 构造方法是一种特殊的成员方法,与其他成员方法不同: 构造方法的名字必须与类名相同; 无类型、可有参数、可重载 会自动生成,可自定义 一般形式:类名(形参); 例: Stu(int age); 当用户没自定义构造方法时,系统将会执行默认构造方法,当用户自定义一个

    2024年02月11日
    浏览(34)
  • C++中的深拷贝和浅拷贝介绍

    对于基本类型的数据以及简单的对象,它们之间的拷贝非常简单,就是按位复制内存。例如: b 和 obj2 都是以拷贝的方式初始化的,具体来说,就是将 a 和 obj1 所在内存中的数据按照二进制位(Bit)复制到 b 和 obj2 所在的内存,这种默认的拷贝行为就是浅拷贝,这和调用 me

    2024年02月07日
    浏览(36)
  • 关于C++拷贝控制

    通常来说,对于类内动态分配资源的类需要进行 拷贝控制 :要在拷贝构造函数、拷贝赋值运算符、析构函数中实现安全高效的操作来管理内存。但是资源管理并不是一个类需要定义自己的拷贝控制成员的唯一原因。 C++ Primer 第5版 中给出了一个Message类与Folder类的例子,分别

    2024年02月08日
    浏览(21)
  • C++——拷贝构造函数

    (用旧对象去构造新对象) 拷贝构造函数,又称复制构造函数,是一种特殊的构造函数,它由编译器调用来完成一些基于同一类的其他对象的构造及初始化。 参数的类型:   值类型(不行,会产生递归); 指针类型(能实现要求,但会出现歧义(感觉a的地址给b构造));

    2024年02月02日
    浏览(28)
  • C++(13):拷贝控制

    一个类通过定义五种特殊的成员函数来控制这些操作,包括: 拷贝构造函数 (copy constructor)、 拷贝赋值运算符 (copy-assignment operator)、 移动构造函数 (moveconstructor)、 移动赋值运算符 (move-assignment operator)和 析构函数 (destructor)。 拷贝和移动构造函数定义了当用同类型的另一

    2024年02月16日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包