C++学习笔记:右值引用和移动语义

右值引用的出现导致了移动语义的产生,让C++的性能产生了提升,这个提升来源与对Copy的减少。

右值引用有什么用呢?

它的作用是调用临时变量,虽然const引用也能调用临时变量,但const引用也能调用栈变量和堆变量,const引用作为形参的时候,我们是分辨不出来是那种变量的引用的,所以const引用它不能导致移动语义的产生;

移动语义是怎么减少Copy的?

我们先思考问题,当我们用一个临时变量去初始化某一个类的时候,我们会经历那些步骤:

看下面的代码:

#include

class String {
public:

	String(const char* ptr) {
		std::cout << "Create" << std::endl;
		this->size = strlen(ptr);
		this->ptr = new char[this->size];
		memcpy(this->ptr, ptr, this->size);
	}

	String(const String& str) {
		std::cout << "Copy" << std::endl;
		this->size = strlen(str.ptr);
		this->ptr = new char[this->size];
		memcpy(this->ptr, str.ptr, this->size);
	}


	~String() {
		std::cout << "Destory" << std::endl;
		delete ptr;
	}

private:
	int size;
	char* ptr;
};

class Test {
public:

	Test(const String& Str)
		:m_Str(Str) {}

private:
	String m_Str;
};


int fun(int&& a) {
	a = 1;
	return a;
}

int main() {
	Test test("LHM");
}

运行结果:

Create
Copy
Destory
Destory
我们创建了两次String,向堆内存申请了两次内存;

1:“LHM”->String类型要生成一个临时变量

2:临时变量传给test中的变量进行Copy

这里我们想,能否让test直接指向临时变量,而不用进行copy,这样做其实没有风险,因为在这个临时变量出现之前,是没有被任何变量依赖的。

这里我们就可以用右值引用了,思路是直接让Test中的ptr等于临时变量中的ptr,然后将临时变量中的ptr指空【有一点像打劫】;

看以下代码:

#include

class String {
public:

	String(const char* ptr) {
		std::cout << "Create" << std::endl;
		this->size = strlen(ptr);
		this->ptr = new char[this->size];
		memcpy(this->ptr, ptr, this->size);
	}

	String(const String& str) {
		std::cout << "Copy" << std::endl;
		this->size = strlen(str.ptr);
		this->ptr = new char[this->size];
		memcpy(this->ptr, str.ptr, this->size);
	}

	String(String&& str) {
		std::cout << "Move" << std::endl;
		this->size = str.size;
		this->ptr = str.ptr;
		str.ptr = nullptr;
	}

	~String() {
		std::cout << "Destory" << std::endl;
		delete ptr;
	}

private:
	int size;
	char* ptr;
};

class Test {
public:

	Test(const String& Str)
		:m_Str(Str) {}
	Test(String&& Str)
		:m_Str((String&&)Str) {}

private:
	String m_Str;
};


int main() {

	Test test("LHM");
}

运行结果:

Create
Move
Destory
Destory
只new了一次

你可能感兴趣的:(学习)