談談C++中的swap函式
1,最通用的模板交換函式模式:建立臨時物件,呼叫物件的賦值操作符。
需要構建臨時物件,一個拷貝構造,兩次賦值操作。
2,針對int型優化:
無需構造臨時物件,異或
因為指標是int,所以基於這個思路可以優化1:
3,針對內建型別的優化: int, flaot, double 等,甚至過載運算子的使用者自定義型別:向量,矩陣,影像等。。。
type a; -- e.g 10
type b; -- e.g 5
a = a+b ; -- a=15,b=5
b = a-b ; -- a=15,b=10
a= a -b ; -- a= 5,b=10
// 無需構造臨時變數。使用基本運算操作符。
4,swap的一些特化:
std::string, std::vector各自實現了swap函式,
string中
第二個swap(Right)進行判斷,如果使用了相同的分配器,則直接交換控制資訊,否則呼叫string::operator=進行拷貝賦值。。。所以建議優先使用swap函式,而不是賦值操作符。
vector中
vector的swap原理跟string完全一致,只有噹噹使用了不同分配器才進行位元組拷貝。其餘情況直接交換控制資訊。
測試用例:
5,Copy and Swap idiom
目的:C++異常有三個級別:基本,強,沒有異常。通過建立臨時物件然後交換,能夠實現過載賦值操作符的強異常安全的執行。
Loki中智慧指標 臨時變數跟this交換,臨時變數自動銷燬~
boost::share_ptr,share_ptr定義了自己的swap函式。
記得本科上C++課,老師特別喜歡拿String來舉例子,面試題也特別喜歡String。。。下面說說String::opreator=函式的優化:
最一般的寫法,特點:使用const string& 傳參防止臨時物件。
優化1,防止自我間接賦值,a = b; c = b; a = c; 如果沒有第一個if判斷,當把c賦給a的時候,刪除了a.itsString,後面的拷貝就會出錯。注意是if(this==&rhs), 而不是if(*this==rhs) .
優化2,不進行拷貝賦值,只是交換控制資訊,而且是強異常安全:
優化3,以最原始的傳值方式傳參,避免臨時物件建立:
最後這張方式主要是對C++新特性rvalue的優化,具體參見:http://en.wikibooks.org/wiki/More_C++_Idioms/Copy-and-swap
6. vector clear and swap trick
vector.clear並只是將size變數置為0,並沒有及時歸還OS,STL仍然持有記憶體,以便後續push_back。實測如下:
vector<int> temp;
此時開啟資源管理器,記憶體如下:
增長vector然後清空:
temp.resize( 1024*1024*20 ); // 80M
temp.clear();
此時資源管理器記憶體:clear以後程式兵沒有及時將記憶體歸還OS。。。通過swap方法:
tmp.resize(1024*1024*20); // 80M
// tmp.clear();
{
std::vector<int>().swap(tmp); // 將記憶體歸還OS
}
退出作用域,臨時物件銷燬。記憶體歸還OS。此時資源管理器中程式記憶體回到1,864K。
附上網路版的String:
參考引用:
1,http://www.vbforums.com/showthread.php?t=245517
2,http://www.cplusplus.com/reference/algorithm/swap/
3,http://codeguru.earthweb.com/forum/showthread.php?t=485643
4,http://stackoverflow.com/questions/1998744/benefits-of-a-swap-function
5,http://answers.google.com/answers/threadview/id/251027.html
C++ idioms
http://en.wikibooks.org/wiki/Category:More_C%2B%2B_Idioms
Copy and Swap idiom
http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom
History:
20140401 - add 6 vector clear and swap trick!
相關文章
- 談談JS中的函式劫持JS函式
- 談談JS中的函式節流JS函式
- 淺談Swift中的函式式Swift函式
- 淺談Kotlin中的函式Kotlin函式
- 談談函式的命名規範函式
- 談談 C++ STL 中的迭代器C++
- 談談交叉熵損失函式熵函式
- 淺談eval函式函式
- 淺談生成函式函式
- 淺談尤拉函式函式
- C++中的enum淺談C++
- 淺談C++指標直接呼叫類成員函式C++指標函式
- 淺談javascript的函式節流JavaScript函式
- 淺談API函式呼叫的方法API函式
- 淺談php count()函式方法PHP函式
- 老生常談-節流函式函式
- 淺談javascript函式節流JavaScript函式
- 函式指標淺談 (轉)函式指標
- 二談三角函式函式
- 淺談Numpy中的shape、reshape函式的區別函式
- 淺談C語言中函式的使用C語言函式
- 談談Fragment的建構函式、重新建立(recreate)及相關Fragment函式
- 淺談js函式節流和函式防抖JS函式
- C++中的strrev函式C++函式
- 再談Linux下的swap分割槽薦Linux
- 談談 react 中的 keyReact
- 淺談匿名函式和閉包函式
- 談談c++的初始化工作(1) (轉)C++
- 談談c++的初始化工作(2) (轉)C++
- 談談c++的初始化工作(3) (轉)C++
- 談談c++的初始化工作(4) (轉)C++
- 給妹子講python-S01E17談談函式的基本特徵Python函式特徵
- C++中strlen函式C++函式
- C++中函式呼叫的用法C++函式
- C++中的函式簽名C++函式
- C++ 中的虛擬函式C++函式
- C++中的回撥函式C++函式
- 談談對中斷的理解