C++string深拷贝的进阶写法(现代写法)。

 string s1("hello world");

string s2(s1);

 s2(s1)需要用到拷贝构造函数,大多数情况下,我们写string拷贝构造函数我们会这样写,创建一个新空间后,把内容依次考入。 

string(const string& s)
	{
		 _str = new char[s._capacity+1];
		_size = s._size;
		_capacity = s._capacity;
		strcpy(_str, s._str);
	}

现在我们把上面这种写法叫传统写法。 下面是我们的进阶写法。(进阶写法不是为了提高效率,是为了代码更简洁。 )

string(const string & s)
	{
		string tmp(s._str);//构造函数
		swap(_str, tmp._str);
		swap(_size, tmp._size);
		swap(_capacity, tmp._capacity);
	}

这里面的swap库模板如下。 

目前这是个不完善的进阶写法。我们继续往下看。

交换前。

 交换后

但是出拷贝构造函数时,tmp要释放,要调用析构函数,此时tmp的_str已经变成和原先this->_str一样的值,然而因为有的编译器不默认把_str设为NULL而是其他随机值的,那么tmp释放,调用析构函数,delete或free释放不是new或malloc等动态开辟的空间的话,就会报错,而delete或free对空指针释放不报错。

所以,为了解决这个问题,我们可以采用先把_str初始化为空的办法。此时tmp和this->_str交换地址后,tmp得到的是NULL,此时析构函数里面的delete或free不会报错。

string(const string& s)
		;_str(nullptr)
		, _size(0)
		, _capacity(0)
	{
		string tmp(s._str);//构造函数
		swap(_str, tmp._str);
		swap(_size, tmp._size);
		swap(_capacity, tmp._capacity);
	}

 这里面的swap其实也是std命名空间中的库模板。

此时各项值如下。

下面还需要对上面代码进一步优化。

问题:下面两个有什么区别。

第一个

第二个

上面的是一个其实是需要自己在类里面定义一个swap函数。

上面的第二个,其实是类模板,在上述代码中,T被系统识别为string类型,这里面需要进行三次深拷贝。

(一次拷贝构造,两次赋值)

 

(这部分了解即可)有了模板以后,内置类型必须有构造和析构了。

 这两个都是有意义的。

 

 第二个可以认为是调用int的默认构造。如果是int*j 那么j就是空指针。这两个都是因为为了兼容模板所以产生此现象的。

 下面是s1.swap(s2)方式代替swap(s1,s2)的方法。

void swap(string& s)
	{
		std::swap(_str, s._str);
		std::swap(_size, tmp._size);
		std::swap(_capacity, tmp._capacity);
	}

swap前面如果不写std::的话会报错,因为swap会先在局部找,但是在局部类域找到的只有一个参数的swap,所以会报错。加上std,swap就直接在std里面找。

下面是赋值的进阶写法。 和进阶深拷贝有很多相似之处。

string & = (const string & s)
	{
		if (*this != s)
		{
			string tmp(s);
			swap(tmp);
		}
		return *this
	}

这里面tmp用析构吗?

会析构的,只要定义了局部的对象  出了作用域都要销毁的。

下面string s相当于形参是拷贝构造的,所以可以直接swap进行交换。

string & = (string s)
	{
		swap(s);
	return *this;
	}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

南种北李

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

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

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

打赏作者

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

抵扣说明:

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

余额充值