條款23:寧以non-memeber、non-friend替換member函式
non-member/non-friend可以給物件帶來更大的封裝性,從兩個方面來考慮:1)考慮封裝,越多東西被封裝,它們就越不可見,就越少人看到它,就會越有彈性去改變它;2)考慮物件內的資料,越少**可以看到資料,越多的資料被封裝,那麼我們就越能自由地改變物件資料;
在c++中,可以讓所有的non-member函式放在同乙個命名空間內,然後使用那個命名空間;c++標準程式庫並不是單
一、整體、龐大的標頭檔案,而是很多標頭檔案組合而成的,這就允許客戶只對他們所有的那部分系統形成編譯相依;
條款24:若所有引數都需型別轉換,用non-member代替member函式
對於引數都允許發生隱式轉換的函式,使用non-member函式可以使你的類功能更加具有一致性,而且還支援混合式算術程式設計;具體**分析如下:
const rational operator*(const rational&rhs)const//實現是基於t的copy建構函式和copy assignment完成
2.通常情況下,資料的表現形式都是「以指標指向乙個物件,內含真正的資料」,這種設計模式通常變現為pimpl(pointer to implementation)手法,如:
class widgetimpl;
如果需要交換兩個widget物件,那麼我們唯一需要做的就是交換兩個pimpl指標,但是普通的swap演算法卻是複製了三次widgetimpl;
解決上述問題的乙個方法:就是將std::swap針對widget全特化(模板函式的乙個例項),然後用widget的成員函式呼叫它(寫錯了)用全特化的swap函式來呼叫public swap成員函式,具體**如下:
class widget
3.如果widget和widgetpimpl都是class templates而非class,那麼我們重新定義非成員函式;
template
void swap>(widget&a,widget&b) //不合法,錯誤
原因是我們企圖對function template偏特化,但是c++只允許對class template偏特化;
引申:std是乙個特殊的命名空間,其管理規則也比較特殊,客戶可以全特化(例項化)std內的template,但是不可以新增新的templates(class或者templates或者其他的任何東西)到std裡頭,c++禁止這類行為,但是編譯器卻不會報錯,但是軟體可能會出現不可預期的行為;
解決上述問題的乙個辦法:新增乙個過載函式來代替我們要做的偏特化乙個function template行為,我們還是宣告乙個non-member swap函式讓他呼叫member swap,但不再宣告將那個non-member swap宣告為std::swap的特化版本,具體實現**如下:
templatetemplate
class widget //優先呼叫t專屬版本,即public swap成員函式
swap(pimpl,other.pimpl); //並在該版本不存在的情況下呼叫std內一般化的版本
結論:1)如果swap預設實現碼可以實現你的class或者class template提供可接受的效率,你不需要做任何事情;
2)如果swap預設碼不夠實現你的效率,你可以:
a)提供乙個public swap成員函式,讓它處理兩個物件值;
b)在你所在的class或者template所在的命名空間內提供乙個non-member swap,並令它呼叫上述swap成員函式;
c)如果你在編寫乙個class(而非class template),為你的class特化std::swap,並令它呼叫你的swap成員函式。
3)如果你呼叫swap,確定包含乙個using宣告式,以便std::swap在你的函式內**,然後不加namespace,單純呼叫swap(使swap函式有更多的選擇);
成員版的swap絕不可能丟擲異常,因為swap的乙個最好應用就是幫助classes提供強烈的異常安全性保障(以copy建構函式和copy assignment操作符為基礎的);
第七天學習
練習題 1 以下類定義中哪些是類屬性,哪些是例項屬性?class c num 0 def init self self.x 4 self.y 5 c.count 62 怎麼定義私有 法?3 嘗試執行以下 並解釋錯誤原因 4 按照以下要求定義乙個遊樂園門票的類,並嘗試計算2個 1個小孩平日票價。要求 ...
Java學習第七天
類成員 static成員 當使用例項來訪問類成員時,系統底層依然是委託該類來訪問類成員。因此,即便該類例項為null,她依然可以訪問所屬類的類成員。例如 package lesson5 單例模式 singleton 主要通過靜態變數 靜態方法和private構造方法完成。例如 package les...
C 學習第七天
c 中的params引數 引數陣列 1 params引數是陣列。呼叫方式可以陣列方式,也可以單個元素方式。static void test string name,params int scores console.writeline 你好,你的scores is name,sb test 劉德華 ...