前言
本文主要归纳总结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()
{