初次探究:深拷贝与浅拷贝在代码中的应用场景

初探浅拷贝

前言:什么是浅拷贝?

浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。即默认拷贝构造函数只是对对象进行浅拷贝复制

  • 这是一段浅拷贝的代码(我们可以看看其中的问题)
#include<iostream>
using namespace std;
class String
{
public:
	String( char *str="")
	{
		cout << "create String Obj:" <<this<< endl;
		m_data = (char*)malloc(strlen(str) + 1);
		strcpy(m_data, str);

	}
	String(const String &s)
	{
		m_data = s.m_data;//将s.m_data指向的空间地址赋值给m_data指针
	}
	~String()
	{
		cout << "free String Obj:" << this << endl;
		free(m_data);
		m_data = nullptr;
	}
private:
	char *m_data;
};
void main()
{
	String s("zhb");
	String s1(s);
}
m_data=s.m_data

这条语句实行的就是浅拷贝,打开监视器可以看到:
在这里插入图片描述
当我们进行赋值语句时:例如:

void main()
{
	String s("zhb");
	String s1;
	s1 = s;//赋值语句
}
**程序会发生崩溃!究其原因我们可以看一下赋值语句的原型:


	String operator=(const String &s)
	{
	if (this != &s)
	{
	m_data = s.m_data;
	}
	return *this;
	}

这里只是将s.m_data指向的空间地址赋值给m_data,因为浅拷贝造成了两个对象的成员指向了同一块空间,所以在程序执行之后会发生崩溃,在这种情况下为了避免程序崩溃我们可以将程序改造。

#include<iostream>
using namespace std;
class String
{
public:
	String( char *str="")
	{
		cout << "create String Obj:" <<this<< endl;
		m_data = (char*)malloc(strlen(str) + 1);
		strcpy(m_data, str);

	}
	/*
	String(const String &s)
	{
		m_data = s.m_data;//将s.m_data指向的空间地址赋值给m_data指针
	}
	*/
	String(const String &s)
	{
		m_data = (char*)malloc(strlen(s.m_data) + 1);
		strcpy(m_data, s.m_data);
	}
	String operator=(const String &s)
	{
		if (this != &s)
		{
			free(m_data);
			m_data = (char*)malloc(strlen(s.m_data) + 1);
			strcpy(m_data, s.m_data);
		}
		return *this;
	}
	~String()
	{
		cout << "free String Obj:" << this << endl;
		free(m_data);
		m_data = nullptr;
	}
private:
	char *m_data;
};
void main()
{
	String s("zhb");
	String s1;
	s1=s;
}

在这种情况下我们可能觉得深拷贝会比浅拷贝好一点,至少能避免同一块空间被释放两次,但事实并非如此。

我们可以假设一种情形:
对象s与对象s1的私有成员m_data现在指向的是同一片空间,此时如果对象s1想更改m_data管理空间的值,那么s所管理空间的值也就发生了改变,这对于s来说显然是不公平的,下一篇博客我将会分享深浅拷贝在另一种情况下的使用

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值