带右值引用的拷贝构造函数和运算符重载函数

考虑一个占用堆资源类对象的拷贝构造和赋值运算符重载函数,当我们用一个临时对象去拷贝构造一个新对象或者赋值给一个已经存在的对象时,会出现一下的问题:如string类

#include <iostream>
#include <cstring>
using namespace std;

class MyString {
private:
	char *mptr;
public:
	MyString(const char *src = nullptr) {
		cout << "MyString(const char*)" << endl;
		if (src != nullptr) {
			mptr = new char[strlen(src) + 1];
			strcpy(mptr, src);
		} else {
			mptr = new char[1];
			*mptr = '\0';
		}
	}


	MyString(const MyString& src) {
		cout << "MyString(const MyString&)" << endl;
		mptr = new char[strlen(src.mptr) + 1];
		strcpy(mptr, src.mptr);
	}
		
	MyString& operator=(const MyString& src) {
		cout << "operator=(const MyString&)" << endl;
		if (this == &src) {
			return  *this;
		}
		delete[] mptr;
		mptr = new char[strlen(src.mptr) + 1];
		strcpy(mptr, src.mptr);
		return *this;
	}

	~MyString() {
		cout << "~MyString()" << endl;
		delete[] mptr;
		mptr = nullptr;
	}

	const char* c_str() const {
		return mptr;
	}
};

MyString getString(MyString &s) {
	const char* t = s.c_str();
	MyString res(t);
	return res;
}

int main() {
	MyString s1("aaaaaaaaaaaaaaaaaaaaaaaaaaa");
	MyString s2;
	s2 = getString(s1);
	return 0;
}

1.当我们用临时对象去拷贝构造一个新对象时。
MyString res = MyString(“aaaa”);
在这里插入图片描述
显然,这样做很不合理,很浪费!!!你临时对象用完就析构了,还不如直接给我新对象用,避免开辟新空间,避免拷贝!!!
在这里插入图片描述

到这里就引出了第一个主题,带右值引用的拷贝构造函数。因为临时对象是右值。临时对象用完就要析构的,那就把临时对象占用的资源直接给新对象就好了。这样做一方面避免了在原来拷贝构造函数需要首先申请空间,然后进行拷贝的麻烦。另一方面避免临时对象析构时还有释放堆资源的麻烦,一举两得!!!

MyString(MyString &&src) {
	mptr = src.mptr;
	src.mptr = nullptr;
}

2.当我们用临时对象去赋值一个已经存在的对象时。这里指的对象都是持有堆资源的对象。
首先,被赋值的对象要释放自己占用的堆资源,然后申请一个和临时对象指向堆资源一摸一样大小的空间,之后将临时对象指向堆空间的内容拷贝到自己的堆空间中。
这里同样存在着上边的问题,我临时对象给你赋值完我就析构了,堆资源也在析构函数中被释放了,但是你被赋值的对象还得申请空间,还得拷贝,你直接用临时对象的那块堆资源不就好了。
在这里插入图片描述

问题就处在临时对象赋值完就析构了,与其白白浪费,不如拿来直接使用,有点“偷”的感觉!!!
在这里插入图片描述

MyString& opeator=(MyString &&s) {
	if (this == &s) {
		return *this;
	}
	delete[] mptr;
	mptr = s.mptr;
	s.mptr = nullptr;
	return *this;
}

结论:
至此,通过一个例子我们总结出了带右值引用的拷贝构造函数和运算符重载函数所带来效率的提升,以及为什么可以这样处理的原因。在实际开发中,当出现一定要用临时对象作为返回值,要用临时来进行赋值时,我们可以为其类实现带右值引用的拷贝构造函数和运算符重载函数,在程序的效率上会得到很大的提升。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值