swap function & copy-and-swap idiom

來源:互聯網
上載者:User

標籤:nbsp   std   guid   c++ prime   guide   prim   交換   foo   資料   

在C++中,眾所周知在一個資源管理類(例如含有指向堆記憶體的指標)中需要重新定義拷貝建構函式、賦值運算子以及解構函式(Big Three),在新標準下還可能需要定義移動建構函式和移動賦值運算子(Big Five)。但實際上,這條規則還可以有一個小擴充。就是在資源管理類中,往往需要重新定義自己的swap函數來作為最佳化手段。

1. swap函數

首先考察如下例子,假設類HasPtr中含有一個指向string的指標 *ps 和一個int類型值value。

class HasPtr {    public:        ...        ...        ...    private:        string* ps;        int value;};

則如果沒有定義自己的swap函數的話,調用標準庫的std::swap相當於進行如下動作:

HasPtr temp = v1;v1 = v2;v2 = temp; 

這裡v1中的string拷貝了兩次,造成了不必要的效率上的浪費。

其實我們知道,這裡swap只需交換指標指向就可以,所以我們可以寫出如下自訂版本的swap函數:

class HasPtr {    friend void swap(HasPtr& lhs, HasPtr& rhs);    ...    ...};inlinevoid swap(HasPtr& lhs, HasPtr& rhs) {    using std::swap;    swap(lhs.ps, rhs,ps);    swap(lhs.value, rhs.value);}

注意: 這裡有一點值得注意的是,函數調用的時候應該寫成swap,而非std::swap形式。這是因為如果HasPtr含有某一特定類型(如Foo類型)的成員foo,則如果Foo定義了自己的swap函數的swap函數的話,應該調用其自訂的swap函數,否則調用標準庫的std::swap。

所以如下形式1是不對的,應該寫成形式2所示。

//形式1void swap(HasPtr& lhs, HasPtr& rhs) {    std::swap(lhs.foo, rhs.foo);}//形式2void swap(HasPtr& lhs, HasPtr& rhs) {    using std::swap;    swap(lhs.foo, rhs.foo);}

 

2. copy and swap idiom

定義了swap函數的類常用swap來定義他們的賦值運算子,即copy and swap技術。

這樣做可以做到天然的異常安全並且正確處理自我賦值問題,是簡潔高效安全的寫法。(為什麼其他方法存在異常安全或自我賦值問題可以參加effective c++條款11)

上述例子使用copy and swap技術定義賦值運算子如下:

HasPtr& HasPtr::operator=(HasPtr rhs) {    swap(*this, rhs);    return *this;}

可以看出,不同於一般的賦值運算子,其參數採用傳值方式,而非引用。它與如下代碼功能上等價,但效率上更高(將copy動作移至函數參數構造階段)

HasPtr& HasPtr::operator=(const HasPtr& rhs) {    HasPtr temp(rhs);    swap(*this, temp);    return *this;}

這兩種方式均可以完美解決異常安全和自我賦值問題。第一種方法被C++ primer和C++編程規範所推薦,Scott Meyers在effective c++中表達了一些對其可讀性的憂慮,但如果掌握好copy and swap idiom,還是應該推薦採用第一種寫法產生更高效的代碼。

 

參考資料:

1.Stanley B. Lippman / Josée Lajoie / Barbara E. Moo,  C++ Primer 中文版(第 5 版)[M].  電子工業出版社,2013

2.Meyers S. Effective C++[M]. Addison Wesley, 2005.

3.Sutter H, Alexandrescu A. C++ Coding Standards: 101 Rules, Guidelines, and Best Practices (C++ in Depth Series)[M]. Addison-Wesley Professional, 2004.

4.關於swap and copy idiom問題在stackoverflow上的解答: http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom

 

swap function & copy-and-swap idiom

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.