c++左值和右值引用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38126105/article/details/82831118

左值和右值

左值和右值从字面意思来看,就是等号的左右两边的意思,但其实不是这样的,左值是有名字的,是可以取到地址的,而右值是没有名字的,是不可以取地址的。其实可以简单的理解为凡是可以取到地址的变量都是左值。左值具有右值的一切属性。左值和右值的提出是为了避免非必要的拷贝和临时对象而产生的。

int a=10;//a 是左值,10是右值
int b; //b是左值
int c= 2+3;//c是左值,3是右值
int d =a +c;//d是左值,a+c是右值。

值语义和引用语义

值语义:作为参数传入函数中,需要在复制一个作为形式参数,他的变化不会影响到原来的变量,两个变量拥有的存储空间是独立的。
引用语义:变量引用赋值后,两个变量只有一份的存储空间,相互之间可以理解为是别名,操作任意一个变量,就可以认为是操作另外一个变量,效果完全一样。

左值引用和右值引用

左值引用只能绑定到左值,不能绑定到右值。如

int& i =40;//该写法是错误的

int i =40;
int& j =i;//左值引用绑定左值 

但是可以将一个右值绑定到const左值引用上:

int const& i =45;

左值引用和右值引用的用法
int a =4
int& b = a; // 左值引用,&
int&& b = a ;//右值引用,&&
借助左值引用和右值引用,我们可以对拷贝构造函数和assignment(赋值运算)进行重载。

移动语句

头文件为 中的std::move可以保证对象被move而不是被拷贝。需要注意的是:std::move(X)意味着调用X的move语义(若有提供的话),否则调用X的copy语义。对于大型的动态结构,这样可以节约大量的内存开支。
还需要注意的是,必须确保被传对象的任何改动(value)的任何改动,特别是析构,都不至于冲击新对象(如今拥有value)的状态。因此必须清除被传入的实参的内容,例如将nullptr赋值给“指向了容器元素”的成员函数。在一次move之后,对象处于有效但是不确定的状态。移动语句在thread类库中被广泛使用。

#include <string>
#include <iostream>
using namespace std;
class X
{
private:
	int* data;
public:
	X() :data(new int[100000])
	{
		cout << "构造函数被调用" << endl;
	}
	~X()
	{
		cout << "析构函数被调用" << endl;
		delete data;
	}
	X(const X& rhs) :data(new int[100000])
	{

		std::copy(rhs.data,rhs.data+ 100000,data);
		cout << "拷贝构造函数被调用" << endl;
	}

	const X& operator=(const X& rhs)
	{
		if (&rhs == this)
		{
			return *this;
		}
		std::copy(rhs.data,rhs.data+ 100000, data);
		cout << "重载等号运算符被调用" << endl;
		return *this;

	}
	X(X&& other):data(other.data)
	{
		cout << "移动构造函数被调用" << endl;
		other.data = nullptr; //切记不可忘记
	}
};
void do_stuff(X&& _x)
{
	//注意一个右值引用参数可以绑定到右值,但是在函数内部,却是被视为左值的,如接下来的这个
	X a(_x);	//调用拷贝构造函数,而不是移动构造函数
	X b(std::move(_x));	//调用移动构造函数
}
int main()
{
	/*X x1;
	X x2 = x1;//调用的是拷贝构造函数,而不是重载运算符,切记
	X x3 = std::move(x2); //移动构造函数被调用*/
	//do_stuff(X());//调用一次构造,一次拷贝构造,一次移动构造
	X x;
	//do_stuff(x); 无法编译成功,因为左值是无法被绑定到右值引用的,除非使用std::move(),或者static_cats<X&&>
	do_stuff(std::move(x));
}

猜你喜欢

转载自blog.csdn.net/m0_38126105/article/details/82831118
今日推荐