- 引用
通常所說的引用,也稱左值引用,某個變量的別名。最經典的一個應用就是作爲函數參數,地址拷貝代替值拷貝,提高性能。
其實用指針也能做到同樣的效率,不過就是不那麼“友好”。如下,他們的反彙編代碼都是一致的,它們本質上都是地址。
int *pa = &a;
00B65619 lea eax,[a]
00B6561C mov dword ptr [pa],eax
int &refa = a;
00B6561F lea eax,[a]
00B65622 mov dword ptr [refa],eax
-
右值引用是個什麼東西呢?
我們先說一下右值,右值有人說,只能往等號右邊放的就是右值。
這個定義是不嚴謹的,反例就是字符串常量,它們是存放在靜態文本區的。
右值包括字面常量、類似x+y等的表達式還有函數的返回值(非引用類型)等臨時對象
右值引用,如上圖,會與右值的地址關聯在一起。簡言之,就是將沒有名字的臨時變量起了個名字。 -
右值引用有什麼用呢?
引入右值引用是爲了減少不必要的拷貝。1中的例子,還體現不出它的優勢,甚至可以說脫了褲子放屁——多此一舉。
但面對複雜對象的時候,它的優勢就體現出來了。如下
#include<iostream>
using namespace std;
class Demo {
public:
Demo(int v) {
value = v;
}
private:
int value;
};
Demo getTemp()
{
return Demo(12);
}
int main()
{
Demo d(10);
Demo &ref_d = d;//左值引用
Demo &&rv_d = Demo(11);//右值引用
d = getTemp();//觸發一次值拷貝
Demo &&rv_dd = getTemp();//拷貝地址
return 0;
}
通過彙編代碼,我們可以看出使用右值引用“接收”返回值,減少了一次拷貝。
其實,這種情況也不一定能體現出右值引用的優勢,如下
Demo d = getTemp();//編譯會進行優化
Demo &&rv_dd = getTemp();//拷貝
右值引用更重要的一個作用還是移動語義和完美轉發,接下來的博文會分析。