C 11 右值引用與move語義

2021-07-04 18:07:32 字數 2026 閱讀 5326

1. 右值引用

1.1 右值

右值就是指在下乙個分號後(更準確的說是在包含右值的完整表示式的最後)銷毀的臨時物件。

對於c++ 11,編譯器會依據引數是左值還是右值在複製建構函式和move建構函式間進行選擇。怎樣區分呢?

the distinguishing criterion is: if it has a name, then it is an lvalue. otherwise, it is an rvalue.

以右值引用為引數的建構函式像這樣:

string(string&& that)   // string&& is an rvalue reference to a string

1.2 copy-and-swap

與(create-temporary-and-swap)不同。

when to implement a class that manages a resource, remember the rule of three:

if you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them.

這個原則被成為the big three或者rule of three。destructor和copy constructor其實都比較好寫,但想寫乙個完美的assignment operator overloading則是一件略有挑戰性的事情。這種情況下,copy-and-swap idiom(以下簡稱為casi)就應運而生了。

casi的執行過程大抵是這樣的:首先使用copy constructor建立乙個資料的local copy,然後使用乙個swap function來把老的資料替換成這個local copy中的新資料。函式結束時,local copy自動銷毀,我們就只剩下了新的資料。

1.3 賦值建構函式

對move語義來說,下面**成為move-and-swap慣用法:   

string& operator=(string that)    // note the missing reference    

為什麼沒出現引用符呢?

複製賦值操作符和轉移賦值操作符可以合併到一起,形成乙個以值為引數的統一賦值操作符:

x& x::operator=(const x&);   // copy assignment operator

x& x::operator=(x&&); // move assignment operator

合併為:

x& x::operator=(x source) // unified assignment operator

注意到我們是直接對引數that傳值,所以that會像其他任何物件一樣被初始化,那麼that是怎樣被初始化的呢?對於c++ 98,答案是拷貝建構函式,也就是copy and swap的慣用法。對於c++ 11,編譯器會依據引數是左值還是右值在複製建構函式和轉移建構函式間進行選擇。

2. move語義

2.1 將左值轉化為右值

void func(string&& str_right)

string a("something");

func( a ); // error, a 是左值

func( std::move(a) ); // ok.

注意即便std::move(a)是右值,但它自己並不生成乙個臨時物件。

例如:

std::vectorreturn_vector(void)

; return tmp;

}

2.2 對模板來說:

template

void foo(t&&);

t&&不是乙個右值引用,而是乙個通用引用型別,它也以指向左值。

ref:

C 11右值 右值引用以及move語義

1 字面常量 1 3,2 等 2 臨時物件 返回非引用型別的函式,算術 關係 位以及後置遞增 遞減原算符 注意 左值引用的函式,賦值 下標 解引用和前置遞增 遞減運算子返回都為左值 3 無名物件 4 一般函式的返回值也為右值 class myclass myclass 右值 1 右值引用只能繫結到臨...

C 11 中 的Move語義 和 右值引用

c 是用來產生更快的 但是c 中的臨時物件降低了c 的效能。某些臨時物件可以被編譯器優化 比如,函式返回值優化 但是有時候臨時物件會造成嚴重的物件拷貝 比如deep copy 舉例如下 include using namespace std vectordoublevalues const vect...

C 11中的右值引用及move語義程式設計

c 0x中加入了右值引用,和move函式。右值引用出現之前我們只能用const引用來關聯臨時物件 右值 造孽的vs可以用非const引用關聯臨時物件,請忽略vs 所以我們不能修臨時物件的內容,右值引用的出現就讓我們可以取得臨時物件的控制權,終於可以修改臨時物件了!而且書上說配合move函式,可以大大...