【C++】深拷贝以及string类的其传统版与现代版写法

浅拷贝:

浅拷贝,也称为拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,还是按照正常的状态来处理,所以当继续对资源项操作时,就会发生访问违规。要解决浅拷贝问题,C++中引入了深拷贝。

深拷贝:

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。

1、传统版写法的string类

class String
{
public:
	String(const char* str = "")
	{
		//构造string类对象时,如果传递nullptr指针,认为程序非法,此处断言
		if (str == nullptr) {
			assert(false);
			return;
		}
		_str = new char[strlen((str)+1)];
		strcpy(_str, str);
	}

	String(const String& s)
		:_str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}

	String& operator=(const String& s)
	{
		if (&s != this) {
			char* pStr = new char[strlen(s._str) + 1];
			strcpy(pStr, s._str);
			delete[] _str;
			_str = pStr;
		}
		return *this;
	}

	~String()
	{
		if (_str) {
			delete[] _str;
			_str = nullptr;
		}
	}
private:
	char* _str;
};

 2、现代版写法的string类

观察上面给出的传统版写法string类,我们可以发现,在构造、拷贝构造以及赋值中,代码的重复度很高,人们为了解决这个问题,又给出了string类的现代版写法。

class String
{
public:
	String(const char* str = "")
	{
		if (str == nullptr) {
			str = "";
		}
		_str = new char[strlen(str) + 1];
		strcpy(_str, str);
	}
	String(const String& s)
		:_str(nullptr)
	{
		String strTmp(s._str);//根据s创建一个临时对象,此对象具有资源
		swap(_str, strTmp);//将这个对象与_str交换,_str拿到这个资源,而这个临时对象得到nullptr
	}

	String& operator=(String s)
	{
		//在传统的赋值中,参数传入的是一个对象的引用,此处使用了直接传值的办法
		//在传引用的时候,我们也需要进行this!=&s的判断,此时传值,一定不需要这步判断
		//且传引用时,如果采用swap的方法,我们还需临时创建一个对象,来完成。
		//但如果直接传值,我们知道在实现的时候,它会自动利用传过来的值创建一个临时对象
		//我们就可以直接使用s._str了,非常巧妙
		swap(_str, s._str);
		return *this;
	}

	~String()
	{
		if (_str) {
			delete[] _str;
			_str = nullptr;
		}
	}
private:
	char* _str;
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值