C++ 深浅拷贝问题

为什么开辟到堆区:因为堆区的内存由程序员创建和释放,在函数体外也可以调用,在使用堆区的时候需要考虑拷贝时防止指针空挂的现象

浅拷贝造成的问题
#include <iostream>
#include <string>
using namespace std;

class Student
{
	public:
		string m_name;
		int* p_age;  // 存放年龄的指针 
		
		Student()
		{
			cout << "默认构造函数调用" << endl;
		}
		Student(string name,int age)
		{
			m_name=name;
			p_age=new int(age);  // 将age存到堆区 
			cout << "有参构造函数调用" << endl;
		}
		~Student()
		{
			if(p_age!=NULL)  // 堆区由程序员调用也需要由程序员释放 
			{
				delete(p_age);  // 释放分配的空间 
				p_age=NULL;  // 将内存指针置空 
			}
			cout << "析构函数调用" << endl;
		}
};

int main(void)
{
	Student s1("Mike",18);
	cout << "NAME:" << s1.m_name << " AGE:" << *s1.p_age << "  address:" << s1.p_age << endl;
	
	Student s2(s1);
	cout << "NAME:" << s2.m_name << " AGE:" << *s2.p_age << "  address:" << s2.p_age << endl;
	return 0;
}

这个时候出发了错误,是因为在系统建立的默认拷贝函数,将s1对象中的m_age的值完整的复制给了s2对象中的m_age的值,执行析构函数时,根据栈的规则,先进后出,释放了掉s2.m_age的值;

为什么判断s1.m_age是否为空,还会产生错误?这是因为浅复制的作用,s1.m_age的字面是不为空,但是实际指向的地址已经在s2.m_age中被释放掉了,所以产生了错误

NAME:Mike AGE:18  address:0x7d1540  // s1.m_age == s2.m_age
NAME:Mike AGE:18  address:0x7d1540

异常情况
图解

深拷贝

浅拷贝其实就是因为缺少拷贝构造函数,使用系统的默认拷贝构造函数所引发的问题

// 系统使用的默认拷贝构造函数
Student(const Student & s)
{
    m_name=s.m_name;
    p_age=s.p_age; // 仅复制值而为独立分开内存空间
}

// 自定义默认拷贝构造函数
Student(const Student & s)
{
    cout << "拷贝构造函数" << endl;
    m_name=s.m_name;
    p_age=new int(*s.p_age); // 在堆区申请地址
}

最终测试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Meaauf

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值