day3 记录晚上刚学的坑 --深浅拷贝

深浅拷贝  面试经典问题,也是常见的(黑马视频中点到)

浅拷贝 :简单的赋值拷贝操作   编译器提供的

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

先来试一下怎么做,首先先创建一个类,然后写入无参构造函数,析构函数,再写入有参构造函数和拷贝构造函数

class Person
{
public:
	//1.构造函数  进行初始化操作   这些是普通构造

	Person()
	{
		cout << "Person无参构造函数的调用" << endl;//如果没有自己构造,系统自己也会构造
	}

	~Person()
	{
		//析构代码,将堆区开辟数据做释放操作
		if (m_Height != NULL) //判断指针是否为空 
		{
			delete m_Height;//手动删除
			m_Height = NULL;
		}
		cout << "Person析构函数的调用" << endl;
	}

	Person(int a , int height)//有参构造函数
	{
		//将传入的人身上的所有属性,拷贝到新的身上
		age = a;
		m_Height = new int(height);//堆区数据需要程序员手动释放
		cout << "Person有参构造函数的调用" << endl;//如果没有自己构造,系统自己也会构造
	}

    //拷贝构造函数的调用   如果使用编辑器默认的拷贝构造函数就是浅拷贝操作
    Person(const Person& p) 
    {
	    cout << "拷贝构造函数的调用" << endl;
	    age = p.age;
	    m_Height = p.m_Height;//编辑器默认实现的是这行代码
	    
    }

	
	int age;
	int* m_Height;//身高开辟到堆区
};

这时写一个test代码

void test01() 
{
	Person p1(18 ,160);
	cout << "p1的年龄" << p1.age <<"身高为"<<*p1.m_Height << endl;	
    Person p2(p1);
	cout << "p2的年龄" << p2.age << "身高为" << *p2.m_Height << endl;
}

//调用测试代码

int main()
{
    test01();
    system("pause");
    return 0 ;
}

在test运行完之后,执行析构的代码,如果没有使用深拷贝操作而使用系统默认的浅拷贝操作会发生错误,原因是int* m_Height是一个指针,指向的是堆区的数据,如果对它进行浅拷贝操作,会将这个地址传给p2,也就是说p2.m_Height的指针也会指向同一个堆区的地址,两个地址相同,当第一个执行到析构的时候,先删除了这个内存,那么第二个调用析构的时候内存为空,这也就是为什么会出现错误的原因了(这里栈有个规则,就是先进后出,所以P2会先被释放)

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

这时候要使用深拷贝来解决浅拷贝带来的问题,自己构造一个深拷贝的拷贝构造函数,主要是再在堆区开辟一个新的空间存放相同的数据,这样指针就不会交叉释放了。

Person(const Person& p) 
    {
	    cout << "拷贝构造函数的调用" << endl;
	    age = p.age;
	    //m_Height = p.m_Height;编辑器默认实现的是这行代码
	    //深拷贝操作
	    m_Height = new int(*p.m_Height);
    }

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

又得开始跑实验咯

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值