Bootstrap

【C++基础】右值引用和move语义总结


前言

本文主要归纳总结C++语法中的右值引用和move语义,方便以后复习。

一、右值引用

1.什么是右值引用

C++11 引入了右值引用,右值引用是一种新类型的引用。右值引用是设计为仅对右值的引用。左值引用是一个&符号,右值引用是&&符号。例如下面case:

int x{
    5 };
int& lref{
    x }; // l-value reference initialized with l-value x
int&& rref{
    5 }; // r-value reference initialized with r-value 5

右值引用只能引用右值,不能引用左值。

右值引用 是否可以绑定 是否可以修改值
可变左值
不可变左值
右值
const 右值引用 是否可以绑定 是否可以修改值
可变左值
不可变左值
右值

右值引用有两个有用的属性。首先,右值引用将初始化对象的生命周期延长到右 值引用的生命周期(当然const 左值引用可以达到这个效果)。其次,非const y右值引用允许右值!

延长声明周期的例子:

#include <iostream>

class Fraction
{
   
private:
	int m_numerator {
    0 };
	int m_denominator {
    1 };

public:
	Fraction(int numerator = 0, int denominator = 1) :
		m_numerator{
    numerator }, m_denominator{
    denominator }
	{
   
	}

	friend std::ostream& operator<<(std::ostream& out, const Fraction& f1)
	{
   
		out << f1.m_numerator << '/' << f1.m_denominator;
		return out;
	}
};

int main()
{
   
	auto&& rref{
    Fraction{
    3, 5 } }; // r-value reference to temporary Fraction

	// f1 of operator<< binds to the temporary, no copies are created.
	std::cout << rref << '\n';

	return 0;
} // rref (and the temporary Fraction) goes out of scope here

作为一个匿名对象,Fraction(3, 5) 通常会在定义它的表达式的末尾离开作用域。但是,由于我们用它初始化右值引用,因此它的声明周期会延长到main函数末尾,我们当然也可以使用该右值引用。

修改右值的例子:

#include <iostream>

int main()
{
   
    
;