C++11 标准新特性: 右值引用与转移语义(点评)
<<C++11 標準新特性: 右值引用與轉移語義>>
原文地址如下
http://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/
對MyString那個例子來說。
我寫了三個測試用例。
1. ? ? MyString a;
? ? ? ? a = MyString("Hello"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??//調用轉移構造函數
? ? ? ? std::vector<MyString> vec;?
? ? ? ? vec.push_back(MyString("World")); ? ? ? ? ? ? ? ?//調用轉移賦值函數
這種情況下,本身MyString("World")這個對象就是一個臨時對象,因此本身他就是右值。因此只要我們給這個類定義了,轉移構造函數和轉移賦值函數,那么在有右值出現的時候。就會調用我們的轉移構造函數和轉移賦值函數了。
2. ? ?MyString b; ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? ? ?b = a; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//調用拷貝構造函數
? ? ? ?vec.push_back(b); ? ? ? ? ? ? ? ? ? ?//調用拷貝賦值函數
因為a,b都為左值,因此會調用拷貝構造函數和拷貝賦值函數。對MyString這個類來說,就會重新分配資源并進行深
拷貝。
3. ? ?MyString c;
? ? ? ?c = std::move(a); ? ? ? ? ? ? ? ? ? ? ??//調用轉移構造函數
? ? ? ?vec.push_back(std::move(b)); ?//調用轉移賦值函數
因為所有的命名對象都只能是左值引用,如果已知一個命名對象不再被使用,而想對它調用轉移構造函數和轉移賦值函數,也就是把一個左值引用當做右值引用來使用,就需要std::move,這個函數以非常簡單的方式將左值引用轉換成右值引用。
另外,大家如果把這三段程序,放到一個main里面測試的話,在定義vec后,需要寫上這句
vec.reserve(4)
因為第一次push_back的時候,vector的capacity是1,第二次push_back的時候,vector的capacity為2,這時,vector應該是要重新分配一塊區域,把第一次push_back的對象也拷貝過去,因此會多打印出一些printf信息,會干擾我們的分析過程。因此,只有一上來把他的capacity分的大一點,就不會再重新分配內存并拷貝對象了。
muduo里面對boost::function的傳遞,基本都是用的std::move,估計function對象里面都有轉移構造函數和轉移賦值函數。
總結
以上是生活随笔為你收集整理的C++11 标准新特性: 右值引用与转移语义(点评)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 招行信用卡可以办几张附属卡
- 下一篇: 招行信用卡掌上生活/微信/网上查账单的方