節選自http://blog.csdn.net/jofranks/article/details/17438955
移動構造函數
在C++11中新加入的特性!
在上一篇blog中我加入了一張圖,可以具體看到移動構造函數的運行原理。
此時,我們偷走了臨時變量的內存空間,據爲己用。節省了開闢空間的時間。
- A(A && h) : a(h.a)
- {
- h.a = nullptr; //還記得nullptr?
- }
可以看到,這個構造函數的參數不同,有兩個&操作符, 移動構造函數接收的是“右值引用”的參數。
還要來說一下,這裏h.a置爲空,如果不這樣做,h.a在移動構造函數結束時候執行析構函數會將我們偷來的內存析構掉。h.a會變成懸垂指針。
移動構造函數何時觸發? 那就是臨時對象(右值)。用到臨時對象的時候就會執行移動語義。
這裏要注意的是,異常發生的情況,要儘量保證移動構造函數 不發生異常,可以通過noexcept關鍵字,這裏可以保證移動構造函數中拋出來的異常會直接調用terminate終止程序。
右值引用:
在上一篇blog中,我們提到過將亡值,他是c++11新增的跟右值引用相關的表達式。
在c++11中,右值引用就是對一個右值進行引用的類型,右值通常不具有名字,我們就只能通過引用的方式找到它的存在了。
比較一下下面兩條語句:
- T &&a = returna();
- T b = returnb();
應該可以看清楚了吧。右值引用就是讓返回的右值(臨時對象)重獲新生,延長生命週期。臨時對象析構了,但是右值引用存活。
不過要注意的是,右值引用不能綁定左值:int a; int &&c = a; 這樣是不行的。
這裏有一個函數就是 move函數,它能夠將左值強制轉換成右值引用。
移動賦值操作符
他的原理跟移動構造函數相同,這裏不再多說。
給出實現代碼:
- A & operator = (A&& h)
- {
- assert(this != &h);
- a = nullptr;
- a = move(h.a);
- h.a = nullptr;
- return *this;
- }