• c++基础(六)——深拷贝与浅拷贝


    一、深拷贝与浅拷贝

    浅拷贝:简单的赋值拷贝操作
    深拷贝:在堆栈区重新申请空间,进行拷贝操作

    (一)、浅拷贝

    (1)、浅拷贝应用

    浅拷贝从定义上我们可以看出,这只是一个简单的赋值操作,也就是将堆区已经申请空间内的数值进行一个赋值,无需重新申请空间。具体样例如下:

    class person_a
    {
    public:
    	person_a()
    	{
    		cout << "这是一个默认构造函数" << endl;
    	}
    
    	person_a(int age)
    	{	
    		m_age = age;
    		cout << "年龄是" << age << endl;
    	}
    	~person_a()
    	{
    		cout << "这是一个析构函数" << endl;
    	}
    
    	int m_age;
    
    };
    
    void test1()
    {
    	person_a p1(18);
    	person_a p2(p1);
    	
    	cout << "p1的年龄为" << p1.m_age << endl;
    	cout << "p2的年龄为" << p2.m_age << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    通过简单的括号赋值法将数值赋值给已经在栈区空间内的变量。

    (二)、浅拷贝所带来的问题

    class person_a
    {
    public:
    	person_a()
    	{
    		cout << "这是一个默认构造函数" << endl;
    	}
    
    	person_a(int age, int weight)
    	{	
    		//将数据创建到堆区
    		m_weight = new int(weight);
    	}
    	~person_a()
    	{
    
    		//将堆区开辟的数据做释放的操作
    		if (m_weight != NULL)
    		{
    			delete m_weight;
    			m_weight = NULL;
    		}
    		cout << "这是一个析构函数" << endl;
    	}
    
    	int *m_weight;
    };
    
    void test1()
    {
    	person_a p1(120);
    	person_a p2(p1);
    	
    	cout << "身高为:"<< *p1.m_weight << endl;
    	cout << "身高为:" << *p2.m_weight << endl;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    当我们运行如上代码时,此时程序会报错:
    在这里插入图片描述
    对于以上的报错说明如下:
    当使用new在堆区开辟一个内存空间时,是需要进行人为清除的,也就是通过析构函数中的内容。当我们通过浅拷贝来将对象p1中的内容拷贝到P2中时,也就将开辟堆区内存空间的地址复制到了p2中。按照内存操作先进后出的原则,当调用P2中的析构函数时,会将堆区新开辟的内存空间清理掉,而执行p1中的析构函数时,由于堆区内的空间已经被清理,则会报出如上的错误。

    所以浅拷贝的弊端就是重复的释放堆区内存。
    这种情况要怎么解决呢?
    我们在复制一段数据的时候,我们可以在堆区内重新开辟一块内存开保存这块数据。这种方法我们称之为深拷贝。

    (二)、深拷贝

    深拷贝我们需要自己构造一个构造函数,其方法如下:

    	//使用指针常量的方法,将数值固定,使指针可以指向指定位置
    	person_a(const person_a &p)
    	{
    	
    		cout << "拷贝构造函数调用" << endl;
    		//编译器默认实现的是如下代码
    		//m_weight = p.m_weight;
    		//深拷贝的操作是:通过new在堆区内开辟一段新的内存空间,并且将数值存放于这一新的内存空间内。
    		m_weight = new int(*p.m_weight);
    	
    	}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    java计算机毕业设计上虞烟草物流配送系统源码+系统+数据库+lw文档+mybatis+运行部署
    达梦数据库配置SSL认证加密
    win中创建django项目后端测试运行
    【云原生之Docker实战】使用Docker部署LibrePhotos照片管理系统
    【智能客服】聊天机器人的过去与未来
    C++命名空间详解
    php 获取网页数据
    【数字IC验证进阶】SoC系统验证和IP模块验证的区别及侧重点分析
    生物素-磺酸-NHS 酯,119616-38-5,Biotin-Sulfo-NHS ester
    [UE]常见数学和插值
  • 原文地址:https://blog.csdn.net/qq_52302919/article/details/126590957