右值引用
右值引用
1. 什么是右值引用
右值引用是C++11新加的一種引用類型,是一種僅能綁定到右值上的引用。不同于左值引用僅用一個(gè)&表示,右值引用用兩個(gè)&&表示。
int x{ 5 }; int& lref{ x }; // l-value refrence initialized with l-value x int&& rref{ 5 } // r-value refrence initialized with r-value 5右值引用有兩個(gè)非常有用的性質(zhì): 1. 右值引用將初始化他們的對(duì)象的壽命延長(zhǎng)到右值引用的壽命;2. 非常量的右值引用允許修改右值。
看一個(gè)實(shí)際例子:
#include <iostream>class Fraction { private:int m_numerator;int m_denominator;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這段代碼打印出:
3/5Fraction{ 3, 5 }是一個(gè)匿名對(duì)象(臨時(shí)對(duì)象),在這行語(yǔ)句結(jié)束的時(shí)候就出了作用域,本來(lái)應(yīng)該被銷毀掉,但是我們用了一個(gè)右值引用來(lái)綁定它,因此延長(zhǎng)了它的生命期,直到main函數(shù)結(jié)束,局部變量rref被銷毀的時(shí)候,這個(gè)臨時(shí)對(duì)象才會(huì)被銷毀。
再看另外一個(gè)例子:
這段代碼執(zhí)行結(jié)果是:
10這里用字面值初始化一個(gè)右值引用,會(huì)創(chuàng)建一個(gè)臨時(shí)對(duì)象,我們可以通過右值引用來(lái)修改這個(gè)對(duì)象。
2. 右值引用作為函數(shù)參數(shù)
右值引用最有用的地方在于作為函數(shù)參數(shù),尤其是在寫重載函數(shù)時(shí),希望對(duì)傳入的左值和右值表現(xiàn)出不同的行為。
void fun(const int& lref) {std::cout << "l-value reference to const." << std::endl; } void fun(int &&rref) {std::cout << "r-value reference." << std::endl; }int main() {int x{ 5 };fun(x); // l-value argument calls l-value version of fun()fun(5); // r-value argument calls r-value version of fun()return 0; }這段代碼打印出:
l-value reference to const. r-value reference.可以看出,當(dāng)傳入的參數(shù)是左值時(shí),調(diào)用的是左值版本的fun(), 當(dāng)傳入的參數(shù)是右值時(shí),調(diào)用的是右值版本的fun()。可是這有什么用呢?這對(duì)于移動(dòng)語(yǔ)義來(lái)說(shuō)是一個(gè)非常重要的特性,后面會(huì)繼續(xù)討論。
再看一個(gè)有意思的例子:
ref是一個(gè)右值引用,那么fun(ref)調(diào)用的是右值引用版本嗎?事實(shí)上,這里調(diào)用的是左值版本的fun()函數(shù)。雖然ref是一個(gè)右值引用,但是這僅說(shuō)明它綁定的對(duì)象是一個(gè)右值,它本身是一個(gè)局部變量,是一個(gè)左值,因此這行代碼調(diào)用的是左值版本的fun()。
3. 不要返回右值引用
在絕大多數(shù)情況下,你都不應(yīng)該返回右值引用。因?yàn)橛抑狄媒壎ǖ膶?duì)象在出作用域之后就會(huì)被銷毀,因此從函數(shù)返回,你智能得到一個(gè)"hanging reference"。
參考資料
[1].https://www.learncpp.com/cpp-tutorial/15-2-rvalue-references/
總結(jié)
- 上一篇: 华为云桌面云中心调试步骤_轻松进行云维护
- 下一篇: MFC+Opencv4+vs2017 显