C++11之右值引用、移动语义

版权声明:guojawee https://blog.csdn.net/weixin_36750623/article/details/84852947

本文涉及的概念:
1. 右值引用
2. std::move
3. 移动构造函数、移动赋值函数


右值引用的主要目的之一是实现移动语义。

1、为什么使用移动语义?
避免拷贝带来的开销

2、std::move
功能:将参数从左值变成右值,使得参数为左值时调用移动语义的函数来避免开销
详细解释:因为传递的参数如果是左值,将会调用拷贝构造、拷贝赋值函数,但是使用std::move将参数转换成右值后,将会调用移动拷贝构造、移动赋值函数。

3、示例代码
看代码可以看到:
① 移动构造函数、移动赋值函数:进行深拷贝,在赋值
② 拷贝构造函数、拷贝赋值函数:转换所有权,不经过拷贝

那么是调用移动语义的函数?还是调用拷贝语义的函数?
编译器会判断传入参数是左值?还是右值?,调用相对应的函数;当想让传入左值时,调用移动语义的函数,先使用std::move将左值转换成右值。

/*
右值引用的主要目的:移动语义,将b的控制权转交给a
避免拷贝过程带来的开销,提高效率
*/

#define _CRT_SECURE_NO_WARNINGS
#pragma once

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

class MyString{
public: 
	MyString();
	MyString(int len);
	MyString(const char* str);
	~MyString();
public:
	MyString(const MyString& another); //默认拷贝构造
	MyString& operator=(const MyString& another);//默认赋值
public:
	MyString(MyString&& another); //移动拷贝构造
	MyString& operator=(MyString&& ano);//移动赋值
public://运算符重载
	MyString operator+(const MyString& another);
	MyString& operator+=(const MyString& another);
	bool operator==(const MyString& another);
	bool operator!=(const MyString& another);
	char& operator[](int index);
	friend ostream& operator<<(ostream& cout, const MyString& myStr);
	friend istream& operator>>(istream& cin, MyString& myStr);
private:
	int len;
	char* str;
};
MyString::MyString(){
	cout << "构造函数" << endl;
	this->len = 0;
	this->str = NULL;
}
MyString::MyString(int len){
	cout << "构造函数" << endl;
	this->len = len;
	this->str = new char[len + 1];
	memset(this->str, 0, sizeof(this->str));
}
MyString::MyString(const char* str){
	cout << "构造函数" << endl;
	if (str == NULL){
		this->len = 0;
		this->str = new char[0 + 1];
		this->str = '\0';
	}
	this->len = strlen(str);
	this->str = new char[this->len + 1];
	strcpy(this->str, str);
}

MyString::~MyString(){
	cout << "析构函数" << endl;
	if (this->str != NULL){
		delete[] this->str;
		this->str = NULL;
		this->len = 0;
	}
}

MyString::MyString(const MyString& another){
	cout << "默认拷贝构造" << endl;
	this->len = another.len;
	this->str = new char[this->len + 1];
	strcpy(this->str, another.str);
}
MyString& MyString::operator=(const MyString& another){
	cout << "默认赋值" << endl;
	if (this != &another){//判断拷贝自身
		if (this->str != NULL)//释放自身垃圾
			delete[] this->str;
		//深拷贝
		this->str = new char[another.len + 1];
		strcpy(this->str, another.str);
		this->len = another.len;
	}
	return *this;//返回对象本身
}

MyString::MyString(MyString&& another){
	cout << "移动拷贝构造" << endl;
	//ano.str的控制权转移给this->str
	this->str = another.str;
	another.str = NULL;
}
MyString& MyString::operator=(MyString&& ano){
	cout << "移动赋值" << endl;
	if (this != &ano){
		if (this->str != NULL)
			delete this->str;
		//ano.str的控制权转移给this->str
		this->str = ano.str;
		ano.str = NULL;
	}
	return *this;
}

MyString MyString::operator+(const MyString& another){
	char* tmp = this->str; //临时变量指向this
	this->len += another.len;
	this->str = new char[this->len + 1];
	strcpy(this->str, tmp);
	strcat(this->str, another.str);
	if (tmp != NULL){
		delete tmp;
		tmp = NULL;
	}
	return *this;
}
MyString& MyString::operator+=(const MyString& another){
	char* tmp = this->str; //临时变量指向this
	this->len += another.len;
	this->str = new char[this->len + 1];

	strcpy(this->str, tmp);
	strcat(this->str, another.str);
	if (tmp != NULL){
		delete tmp;
		tmp = NULL;
	}
	return *this;
}
bool MyString::operator==(const MyString& another){
	return strcmp(this->str, another.str);
}
bool MyString::operator!=(const MyString& another){
	return !strcmp(this->str, another.str);
}
char& MyString::operator[](int index){//注意返回值char&
	if (index > this->len)//索引越界判断
		exit(-1);
	else
		return this->str[index];
}
ostream& operator<<(ostream& cout, const MyString& myStr){
	cout << myStr.str;
	return cout;
}
istream& operator>>(istream& cin, MyString& myStr){
	//1.释放myStr之前的字符串
	if (myStr.str != NULL){
		delete[] myStr.str;
		myStr.str = NULL;
		myStr.len = 0;
	}
	//2.通过cin添加新的字符串
	char buf[4096] = { 0 };
	cin >> buf;
	myStr.len = strlen(buf);
	myStr.str = new char[myStr.len + 1];
	strcpy(myStr.str, buf);
	return cin;
}

void test01(){
	MyString st1("ABC");
	MyString st2(st1);
	MyString st3(std::move(st1));
}
void test02(){
	MyString a("11");
	MyString b("22");
	a = b;
	a = std::move(b);
}
int main(){
	test01();
	test02();
}

猜你喜欢

转载自blog.csdn.net/weixin_36750623/article/details/84852947