首页 > 编程语言 >C++中深拷贝与浅拷贝

C++中深拷贝与浅拷贝

时间:2024-09-08 19:54:37浏览次数:9  
标签:构造函数 未定义 C++ 中深 析构 拷贝 指针 赋值

描述:

在未定义显示拷贝构造函数的情况下,系统调用默认的拷贝函数——即浅拷贝,它能够完成成员的简单赋值拷贝操作。当数据成员中没有指针时,浅拷贝是可行的;

但当数据成员中有指针时,如果采用简单的浅拷贝,则两类中的两个指针将指向同一个地址,当对象快结束时,会调用两次析构函数,执行两次清理,对同一块动态内存执行2次以上释放的结果是未定义的,所以这将导致内存泄露或程序崩溃。所以,此时,必须采用深拷贝。

定义:

浅拷贝:简单的赋值拷贝操作

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

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

示例:

设计了一个没有类而没有提供它的复制构造函数,当用该类的一个对象去给令一个对象赋值时所执行的过程就是浅拷贝,如下

class Person {
public:
	//无参(默认)构造函数
	Person() {
		cout << "无参构造函数!" << endl;
	}
	//有参构造函数
	Person(int age ,int height) {
		
		cout << "有参构造函数!" << endl;

		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);
		
	}

	//析构函数
	~Person() {
		cout << "析构函数!" << endl;
		if (m_height != NULL)
		{
			delete m_height;
		}
	}
public:
	int m_age;
	int* m_height;
};

void test01()
{
	Person p1(18, 180);

	Person p2(p1);

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

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

int main() {

	test01();

	system("pause");

	return 0;
}

总结:

总结:如果属性有在堆区开辟的,一定要自己提供拷贝构造函数,防止浅拷贝带来的问题

标签:构造函数,未定义,C++,中深,析构,拷贝,指针,赋值
From: https://blog.csdn.net/2301_80950699/article/details/142031635

相关文章

  • 南沙信C++陈老师解一本通题:1310:【例2.2】车厢重组
    ​【题目描述】在一个旧式的火车站旁边有一座桥,其桥面可以绕河中心的桥墩水平旋转。一个车站的职工发现桥的长度最多能容纳两节车厢,如果将桥旋转180度,则可以把相邻两节车厢的位置交换,用这种方法可以重新排列车厢的顺序。于是他就负责用这座桥将进站的车厢按车厢号从小到大排列......
  • C++字符串中的string类操作
    愿我如星君如月,夜夜流光相皎洁。                           ——《车逍遥篇》【宋】范成大目录正文:主要特点:基本操作: 代码演示:总结:今天我们接着上次的章节继续,这次我们来说一个为解决上个方法的缺陷而诞生......
  • u盘知识科普:6款u盘防复制防拷贝软件分享(如何防止U盘拷贝资料)
    小李,手握U盘,内含公司最新的产品蓝图。一天,李明不慎将U盘遗落在了咖啡馆的座位上,等他发现时,U盘已不见踪影。几天后,市场上竟出现了与公司产品极为相似的竞品,原来,那名捡到U盘的人轻松复制了其中的数据并泄露给了竞争对手。可见,u盘防复制防拷贝如此重要!那么,我们应如何防止U盘拷......
  • 大二上 C++高级程序设计笔记(1) 栈和c++对c的补充 20240908
    Q1:什么是static类的储存变量?A1:在C++中,static关键字可以用于类成员变量和成员函数,以改变其作用域和生命周期。当static用于类的成员变量时,它具有以下特性:全局唯一性:静态成员变量不属于任何特定的对象实例,而是属于类本身。这意味着无论创建多少个类的对象,静态成员变量都只有......
  • 【C++ Primer Plus习题】12.6
    1大家好,这里是国中之林!❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←问题:解答:main.cpp#include<iostream>#include<cstdlib>#include<ctime>#include"queue.h"using......
  • 【C++ Primer Plus习题】12.5
    大家好,这里是国中之林!❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←问题:解答:main.cpp#include<iostream>#include<cstdlib>#include<ctime>#include"queue.h......
  • 【C++11及其特性】智能指针——shared_ptr
    大家好,这里是国中之林!❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看←shared_ptr目录一.共享性智能指针二.shared_ptr的共享原理三.shared_ptr的构造函数1.普通的2.数组的3.带删除器......
  • 【C++】智能指针
    目录1.智能指针简介2. std::unique_ptr2.1.特点2.2.使用示例3. std::shared_ptr3.1.特点3.2.使用示例4. std::weak_ptr4.1.特点4.2.使用示例5.使用智能指针的注意事项5.1.选择合适的智能指针类型5.2.避免循环引用5.3.谨慎使用自定义删除器5.4.注......
  • Linux 下 C/C++ 程序编译的过程
    目录一、GCC工具链二、编译过程1、预处理2、编译3、汇编4、链接本文将介绍如何将C/C++语言编写的程序转换成为处理器能够执行的二进制代码的过程,包括四个步骤:预处理(Preprocessing)编译(Compilation)汇编(Assembly)链接(Linking)。在此之前,首先来看一下GCC工具链。......
  • C++11/14/17/20 新特性反汇编分析1
    区间for迭代类似于java中的foreach看个例子:数组的区间for迭代我们从第一行开始看,首先把数组a的地址放到eax中,再把eax的值放到[ebp-28h]中,也就是[ebp-28h]存储了元素的首地址,同理[ebp-34h]也存了a的首地址(这里猜测可能是多个变......