C Primer 交換操作

2021-10-02 06:53:21 字數 3060 閱讀 2810

除了定義拷貝控制成員,管理資源的類通常還定義了乙個名為swap的函式。為了交換兩個物件我們需要進行一次拷貝和兩次賦值。

hasptr temp = v1;

//建立v1的值的乙個臨時副本

v1 = v2;

//將v2的值賦予v1()

v2 = temp;

//將儲存的v1的值賦予v2

拷貝乙個類值的hasptr會分配乙個新string並將其拷貝到hasptr指向的位置,而這些拷貝中的記憶體分配都是不必要的。我們更希望swap交換指標,而不是分配string的新副本

string *temp = v1.ps;

//為v1.ps中的指標建立乙個副本

v1.ps = v2.ps;

//將v2.ps中的指標賦予v1.ps

v2.ps = temp;

//將儲存的v1.ps中原來的指標賦予v2.ps

編寫自己的swap函式

class

hasptr

;inline

swap

(hasptr &lhs, hasptr &rhs)

如果乙個類成員有自己的swap函式版本,就不能呼叫標準庫的std::swap(),應該直接呼叫型別特定的swap函式

在賦值運算中使用swap

定義了swap函式的類,通常用swap來定義它們的賦值運算子,這些運算子使用了一種名為拷貝並交換(copy and swap)的技術。這種技術將左側運算物件與右側物件的乙個副本進行交換:

//注意rhs是按值傳遞的,意味著hasptr的拷貝建構函式將右側運算物件中的string拷貝到rhs

hasptr& hasptr::

operator

=(hasptr rhs)

該版本中,並非是引用傳遞,而是值傳遞,rhs是右側運算物件的乙個副本,引數傳遞時拷貝hasptr的操作會分配該物件string的乙個新副本。

在swap呼叫之後,*this中的指標成員指向新分配的string——右側運算物件中string的乙個副本。當賦值運算子結束時,rhs被銷毀,hasptr中的析構函式被執行。此析構函式delete rhs現在指向的記憶體,即,釋放掉左側運算物件中原來的記憶體。

這個技術自動處理了自賦值的情況,它通過在改變左側運算物件之前拷貝右側物件保證了字賦值的正確。

解釋:swap(hasptr&, hasptr&)中對swap的呼叫不會導致遞迴迴圈

解答:在swap函式中又呼叫了swap來交換ps和i,但這兩個型別為指標和整型,屬於內建型別。因此函式呼叫中的swap呼叫被解析為std::swap,而不是hasptr特定版本的swap函式,所以不會導致遞迴呼叫。

為你的類值版本的hasptr類編寫swap函式

inline

void

swap

(hasptr &lhs, hasptr &rhs)

為你的hasptr類定義乙個《運算子,並定義乙個hasptr的vector。為這個vector新增一些元素,並對它執行sort。注意何時會呼叫swap

《運算子直接返回兩個hasptr的ps指向的string的比較結果即可,但需要注意的是,它應該被宣告為const。

#include

#include

#include

#include

using

namespace std;

class

hasptr

//預設建構函式

hasptr

(const hasptr& p):ps

(new

string

(*p.ps)),

i(p.i)

//拷貝建構函式

hasptr&

operator=(

const hasptr&);

//拷貝賦值運算子

hasptr&

operator=(

const string&);

//賦予新string

string&

operator*(

);//解引用

bool

operator

<

(const hasptr&

)const

;//比較運算

~hasptr()

;//析構函式

private

: string* ps;

int i;};

hasptr::

~hasptr()

inline hasptr& hasptr::

operator=(

const hasptr & rhs)

hasptr& hasptr::

operator=(

const string& rhs)

string& hasptr::

operator*(

)inline

void

swap

(hasptr& lhs, hasptr& rhs)

bool hasptr::

operator

<

(const hasptr& rhs)

const

intmain()

cout << endl;

sort

(v.begin()

, v.

end())

;for

(auto p : v)

cout << endl;

return0;

}

類指標的hasptr版本會從swap函式中受益嗎?

預設的swap版本簡單交換兩個物件的非靜態成員,對於hasptr來言,就是交換string指標ps、引用計數指標use和整型值i。因此,預設的swap版本能夠正確處理類指標hasptr的交換,專用swap版本不會有更多受益。

過載 操作符 c primer

istream operator istream in,sales item s double price in s.isbn s.units sold price check that the inputs succeeded if in s.revenue s.units sold price ...

C Primer 過載操作符與轉換

1.不能通過連線其他合法符號來建立任何新的操作符,例如試圖定義乙個operator 操作符以提供求冪操作是非法的 用於內建型別的操作符其含義不能改變,例如 int operator int,int 就是非法的 也不能為任何內建型別定義額外的新的操作符,例如不能定義接受兩個陣列型別運算元的operat...

足跡C primer 26 順序容器操作

forward list 有自己專有版本的insert和emplace forward list 不支援push back和emplace back vector,string 不支援push front和emplace front c.push back t c.emplace back args...