c++左值和右值引用

本文深入探讨了左值和右值的概念,解释了它们在C++中的作用和区别,包括值语义和引用语义,左值引用和右值引用的用法,以及如何通过std::move实现移动语义,优化大型动态结构的内存使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

左值和右值

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

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));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值