原則25:考慮寫出一個(gè)不拋出異常的swap函數(shù)

Effective C++中第25個(gè)原則段多,頗為復(fù)雜酸些,作者用了很長(zhǎng)的篇幅來講這個(gè)原則取募,我在理解這個(gè)原則上也花了不少功夫琐谤。
我還是先敘述一下這個(gè)作者所述的例子吧。
話說在STL有這么一個(gè)泛型算法名叫SWAP玩敏,其功能如其名斗忌,就是用來交換,它能交換兩個(gè)類型的對(duì)象聊品,那更不用說內(nèi)置類型飞蹂,因?yàn)閮?nèi)置類型也可以說是某種類型的對(duì)象吧,只要被交換類型支持復(fù)制COPY操作就行翻屈。但是這個(gè)泛型算法的思路還是讓一個(gè)臨時(shí)變量tmp先接收一個(gè)對(duì)象a陈哑,然后把另一個(gè)對(duì)象b賦給這個(gè)對(duì)象a,之后再把這個(gè)臨時(shí)變量tmp的值再賦給a伸眶。思路很簡(jiǎn)單惊窖,也很正常,然后在某些情況下這種做法帶來的卻是效率的低下厘贼。
作者舉了一個(gè)常見的場(chǎng)景界酒,那就是用指針指向一個(gè)對(duì)象的時(shí)候(pimpl,pointer to implementaion)這種做法具體就是一個(gè)類A用來操作指針嘴秸,這個(gè)指針指向類B毁欣,另一個(gè)類B中的內(nèi)容才是實(shí)質(zhì)的內(nèi)容庇谆。指針很小,但是對(duì)象很龐大凭疮,這個(gè)時(shí)候你再用復(fù)制的方法來交換那花費(fèi)的時(shí)間就不是一般兩般的長(zhǎng)了饭耳,占用的臨時(shí)空間也非常大。如果用泛型算法SWAP來交換兩個(gè)A對(duì)象的話执解,因?yàn)锳對(duì)象中有指針已經(jīng)指向了B的對(duì)象寞肖,再加上SWAP中間的臨時(shí)變量tmp,那么SWAP不僅僅賦值了3個(gè)A對(duì)象衰腌,而且還復(fù)制了3個(gè)B對(duì)象新蟆,而后者并不是我們想要的,其效率之低下由此可見一斑右蕊。而我們想要的只是進(jìn)行到A的指針就可以了琼稻。
那這個(gè)時(shí)候該怎么辦呢?那我們就私人定制一個(gè)A類專屬的SWAP好了饶囚,這就是所謂的SWAP針對(duì)A類的特化欣簇。具體的做法就是弄一個(gè)全特化的SWAP版本,用它來交換給定對(duì)象中所包含的指針坯约,然而這一版本并不能成功因?yàn)檫@個(gè)指針是私有的熊咽。解決這個(gè)問題的辦法你可以考慮使用友元函數(shù),但是基于友元函數(shù)對(duì)于封裝性的破壞闹丐,我們能不用就不用横殴。所以最好的做法就是聲明一個(gè)A類的公有成員函數(shù)SWAP,然后在這個(gè)公有成員的SWAP函數(shù)里面調(diào)用泛型算法只用來交換指針卿拴,這樣它就能訪問A的私有成員指針了衫仑。同時(shí),在同一命名空間下再聲明一個(gè)非成員函數(shù)的SWAP堕花,它的參數(shù)被特化為A類型文狱,這樣它直接調(diào)用實(shí)參對(duì)象,也就是A類型對(duì)象的公有接口SWAP就可以完成交換了缘挽。而這種做法也恰恰符合了STL的風(fēng)格瞄崇。
不過,上面這種做法并不適合泛型函數(shù)級(jí)別上進(jìn)行偏特化壕曼,因?yàn)镃++只允許對(duì)泛型類級(jí)別上進(jìn)行苏研。那一般而言應(yīng)對(duì)這種情況的做法就是寫一個(gè)重載函數(shù),這個(gè)重載函數(shù)只有參數(shù)是特化的腮郊。不過摹蘑,不要往std里面添加重載的泛型函數(shù),也可以說成是你不要往std里面添加新東西轧飞,因?yàn)檫@些都是標(biāo)準(zhǔn)衅鹿。所以撒踪,你還是自己弄個(gè)命名空間然后把這些放到里面去。
有的時(shí)候純粹是為了方便大渤,你希望你的特化SWAP被最大化使用糠涛,你還是應(yīng)該在你自定義的命名空間內(nèi)std的特化版本SWAP和本類的專版,這樣編譯器就會(huì)根據(jù)實(shí)參的具體類型自動(dòng)選擇最合適的版本了兼犯。
另外,SWAP作為成員函數(shù)決不能拋出異常集漾,因?yàn)樗菐椭愄峁┮粋€(gè)異常安全性的保障切黔。不過這一點(diǎn)不適用于非成員函數(shù)的SWAP,因?yàn)樗腔诳截悩?gòu)造函數(shù)和拷貝賦值操作符函數(shù)具篇,而這兩者是可能拋出異常的纬霞。一個(gè)規(guī)律就是你的SWAP效率越高,它的異常安全性越好驱显,一個(gè)特例就是當(dāng)SWAP操作內(nèi)置類型時(shí)SWAP根本不可能拋出異常诗芜。
什么是全特化?就是凡事涉及到泛型類型的地方都用特定類型代替之埃疫。
什么是偏特化伏恐?就是非全特化。
通過上述內(nèi)容作者想表達(dá)3個(gè)觀點(diǎn):
1栓霜、當(dāng)那個(gè)泛型SWAP效率實(shí)在低下時(shí)翠桦,你自己寫一個(gè),但是要確保不拋出異常胳蛮;
2销凑、如果你的SWAP是成員函數(shù),那你一定要用一個(gè)非成員函數(shù)來調(diào)用這個(gè)成員SWAP仅炊,并且特化一個(gè)std::SWAP斗幼;
3、不要往std里添加全新的東西抚垄。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蜕窿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子呆馁,更是在濱河造成了極大的恐慌渠羞,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,816評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件智哀,死亡現(xiàn)場(chǎng)離奇詭異次询,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)瓷叫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門屯吊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來送巡,“玉大人,你說我怎么就攤上這事盒卸∑” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵蔽介,是天一觀的道長(zhǎng)摘投。 經(jīng)常有香客問我,道長(zhǎng)虹蓄,這世上最難降的妖魔是什么犀呼? 我笑而不...
    開封第一講書人閱讀 56,780評(píng)論 1 285
  • 正文 為了忘掉前任,我火速辦了婚禮薇组,結(jié)果婚禮上外臂,老公的妹妹穿的比我還像新娘。我一直安慰自己律胀,他們只是感情好宋光,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炭菌,像睡著了一般罪佳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黑低,一...
    開封第一講書人閱讀 50,084評(píng)論 1 291
  • 那天菇民,我揣著相機(jī)與錄音,去河邊找鬼投储。 笑死第练,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的玛荞。 我是一名探鬼主播娇掏,決...
    沈念sama閱讀 39,151評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼勋眯!你這毒婦竟也來了婴梧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,912評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤客蹋,失蹤者是張志新(化名)和其女友劉穎塞蹭,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體讶坯,經(jīng)...
    沈念sama閱讀 44,355評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡番电,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片漱办。...
    茶點(diǎn)故事閱讀 38,809評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡这刷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出娩井,到底是詐尸還是另有隱情暇屋,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評(píng)論 4 334
  • 正文 年R本政府宣布洞辣,位于F島的核電站咐刨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏扬霜。R本人自食惡果不足惜定鸟,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望畜挥。 院中可真熱鬧,春花似錦婴谱、人聲如沸蟹但。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)华糖。三九已至,卻和暖如春瘟裸,著一層夾襖步出監(jiān)牢的瞬間客叉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工话告, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兼搏,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,628評(píng)論 2 362
  • 正文 我出身青樓沙郭,卻偏偏與公主長(zhǎng)得像佛呻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子病线,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評(píng)論 2 351

推薦閱讀更多精彩內(nèi)容