青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Note of Justin

關(guān)于工作和讀書的筆記

  C++博客 :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
  47 Posts :: 0 Stories :: 45 Comments :: 0 Trackbacks

留言簿(14)

搜索

  •  

積分與排名

  • 積分 - 53242
  • 排名 - 433

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

[原創(chuàng)文章歡迎轉(zhuǎn)載,但請(qǐng)保留作者信息]
Justin 于 2009-12-20

大師說了,C++的設(shè)計(jì)還是有缺陷的:它無法把接口(interface)的設(shè)計(jì)和實(shí)現(xiàn)(implementation)的設(shè)計(jì)完全劃分開來。比如說在一個(gè)類的(接口)聲明當(dāng)中,總是或多或少的會(huì)泄漏一些實(shí)現(xiàn)上的細(xì)節(jié),雖然這樣做與接口的設(shè)計(jì)并沒有太多聯(lián)系。
有同學(xué)說應(yīng)該多放些代碼一起炒冷飯,是個(gè)好主意,下面是書中的修改版本,大致是一樣的。

class ?AClass {
public :
???
void ?interface_1();
???std::
string ?interface_2();
???
// ..
private :
???
// ?implementation?details?are?leaking?as?below..
???std:: string ?internalData_1;
???BClass?internalData_2;
???
// ..
}

這些實(shí)現(xiàn)上的細(xì)節(jié)往往需要引用其他頭文件中相關(guān)對(duì)象的定義(比如說下面的代碼),從而產(chǎn)生了對(duì)這些頭文件的(在編譯時(shí)的)依賴。因此每次這些文件中的某個(gè)有變化時(shí),依賴它的所有文件都需要重新編譯。

#include? < string >
#include?
" BClass.h "
// ..

【注意】這里貌似邏輯不是很順:就算沒有那些私有成員的聲明,接口函數(shù)的返回值如果是string或是BClass等類型,不還是一樣需要依賴引用其他頭文件嗎?其實(shí)這是兩種不一樣的情況,實(shí)現(xiàn)和接口。前面說的實(shí)現(xiàn)細(xì)節(jié)的泄漏是會(huì)導(dǎo)致編譯依賴的,因?yàn)榫幾g器需要了解這些類型對(duì)象的大小進(jìn)而為其分配內(nèi)存空間;但是接口,比如說函數(shù)的返回值或是參數(shù)表中的參數(shù),就不需要編譯器去考慮分配內(nèi)存的問題,因此也就沒有所謂的編譯依賴了。
問題知道了,那么解決辦法呢,大師提出“骨肉分離法”(嗯……其實(shí)是我的杜撰@#¥%):將聲明(declaration)和定義(definition)分開。

呃……下面的比喻,最好吃完飯?jiān)倮^續(xù)。
如果說接口是一個(gè)類的骨架,那么實(shí)現(xiàn)就是他的血肉;如果說聲明讓你摸到了骨頭,那么定義應(yīng)該就是血和肉生長的地方。
根據(jù)骨肉分離法,對(duì)于一個(gè)AClass類,第一步先把血肉(定義/實(shí)現(xiàn))剝離開,只留下骨架。然后找個(gè)盒子(新建一個(gè)類,比如說AClassImpl),把血肉放進(jìn)去。
接下來還有一步,在骨頭盒子里(原AClass類)加一條繩子連著血肉盒子(一個(gè)指向AClassImpl的指針),這樣才不至于讓骨肉真正的分離,只要找到了骨頭盒子,就一定能找到血肉盒子,然后對(duì)于這個(gè)“可憐”的AClass來說,它的全部“零件”都是完整的,啥也沒丟,但是做到了骨肉分離。

也做到了沒有編譯依賴。
因?yàn)閷?duì)于AClass的用戶來說,他們面對(duì)的將是一個(gè)沒有定義的類,這個(gè)類的后繼改動(dòng),只要不涉及接口的改動(dòng),都不會(huì)導(dǎo)致用戶程序的重新編譯。
看到這里想想工作時(shí)看到的代碼,原來前輩也有看過啊……
對(duì)比前面的例程,給一個(gè)“骨肉分離”了的版本吧:

class ?AClassImpl {
// ..
private :
???
// ?implementation?details?are?moved?here..
???std:: string ?internalData_1;
???BClass?internalData_2;
// ..
}


class ?AClass {
public :
???
void ?interface_1();
???std::
string ?interface_2();
???
// ..
private :
???
// ?there?is?only?a?pointer?to?implementation
???std::tr1::shared_ptr < AClassImpl > ?pImpl;
}


// a?constructor:?instantiations?of?AClass?and?AClassImpl?should?always?be?bound?together.
AClass::AClass( // ..)?:?pImpl(new?AClassImpl( // ..))
{
???
// ..
}

前面的文字是自己的理解,而大師的真言是這樣的:

  • 如果可以用指針/引用的話,就不用對(duì)象。
  • 如果可以做到僅依賴聲明,就不要依賴定義。
  • 為定義和聲明分別準(zhǔn)備兩個(gè)頭文件。這樣一來,用戶就可以很簡單做到上面兩點(diǎn)。

如果覺得骨肉分離太殘忍,大師還有另外一個(gè)工具:工廠(factory)。
第二種方法中,抽象類/接口類提供了所有接口的純虛函數(shù)形式:會(huì)有該類的子類去實(shí)現(xiàn)這些接口。與此同時(shí),在抽象類/接口類中還會(huì)有一個(gè)靜態(tài)(static)的工廠函數(shù)(比如create()/produce()/factory()……),這個(gè)函數(shù)實(shí)際上起到了構(gòu)造函數(shù)的作用,它“制造”出子類對(duì)象來完成真正的任務(wù),同時(shí)返回這個(gè)對(duì)象的指針(通常是智能指針如shared_ptr)。憑借這個(gè)返回的指針就可以進(jìn)行正常的操作,同時(shí)不會(huì)有編譯依賴的擔(dān)心。一個(gè)簡陋的代碼見下:

class ?AClass: public ?AClassFactory {
public :
???AClass()?
{}
???
void ?interface_1();
???std::
string ?interface_2();
???
virtual ? ~ AClass();
// ..
}


class ?AClassFactory {
public :
???
virtual ? void ?interface_1()? = ? 0 ;
???
virtual ?std:: string ?interface_2()? = ? 0 ;
???
// ..
??? virtual ? ~ AClassFactory() { /* .. */ }
???
static ?std::tr1::shared_ptr < AClassFactory > ?Produce( /* .. */ )
???
{
??????
// this?factory?function?could?be?more?complicated?in?practice..
?????? return ?std::tr1::shared_ptr < AClassFactory > ( new ?AClass);
???}

// ..
}



// AClassFactory?could?be?used?in?this?way..
std::tr1::shared_ptr < AClassFactory > ?pAClassObject;
pAClassObject?
= ?AClassFactory::Produce( /* .. */ );
// pAClassObject->..

無論是骨肉分離法還是工廠模式,都可以去除編譯依賴。代價(jià)是有的,要為之付出一點(diǎn)點(diǎn)額外代碼執(zhí)行的時(shí)間和空間。這個(gè)代價(jià)又可以通過內(nèi)聯(lián)函數(shù)(inline function)來減小一些。(不過有聽過這種說法:大部分的編譯器都會(huì)將短小的函數(shù)自動(dòng)轉(zhuǎn)成內(nèi)聯(lián)函數(shù)的)
盡管如此,只有在以上做法很明顯地降低了系統(tǒng)的性能的情況下,才可以放棄分離實(shí)現(xiàn)和接口的努力。
這是大師的忠告。
posted on 2010-02-01 09:06 Justin.H 閱讀(2092) 評(píng)論(2)  編輯 收藏 引用 所屬分類: Effective C++ 炒冷飯

Feedback

# re: 讀書筆記:Effective C++ 炒冷飯 - Item 31 減少文件間的編譯依賴 2012-10-02 20:34 xiaolong
只能說降低編譯依賴,但是實(shí)際工作中編譯依賴簡直太大了,而且很多情況下無法避免的吧!  回復(fù)  更多評(píng)論
  

# re: 讀書筆記:Effective C++ 炒冷飯 - Item 31 減少文件間的編譯依賴[未登錄] 2014-11-18 17:00 liu
寫的不錯(cuò),血肉的說法太瘆人了,改成肉吧  回復(fù)  更多評(píng)論
  

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            国产视频一区在线观看| 亚洲精品国偷自产在线99热| 欧美激情中文字幕一区二区| 亚洲欧美日韩视频一区| 日韩视频―中文字幕| 亚洲国产一区在线| 亚洲黑丝在线| 一区二区三区www| 亚洲免费观看在线观看| 亚洲精品在线观| 亚洲第一精品在线| 午夜精品视频一区| 国产精品日本一区二区| 欧美jizzhd精品欧美巨大免费| 国产精品一区视频| 久久亚洲精品网站| 亚洲视频大全| 中文在线不卡| 亚洲视屏在线播放| 一区二区欧美视频| 一区二区三区 在线观看视| 久久综合影音| 日韩视频在线你懂得| 亚洲欧美日韩一区二区| 亚洲一区在线免费| 国产欧美一区二区三区久久 | 久久九九电影| 久久精品女人天堂| 欧美成人综合在线| aa亚洲婷婷| 久久国产综合精品| 欧美日韩在线播放一区| 国产在线欧美日韩| 久久免费视频在线观看| 亚洲香蕉网站| 美女91精品| 国产精品igao视频网网址不卡日韩| 欧美日韩在线三级| 欧美日韩国产免费观看| 久久亚洲精品欧美| 国产欧美大片| 久久久人成影片一区二区三区| 欧美体内she精视频在线观看| 欧美精品久久久久久久久久| 欧美无砖砖区免费| 亚洲国产一区在线观看| 欧美亚洲一区二区三区| 亚洲国产精品一区二区尤物区| 韩日精品在线| 亚洲在线第一页| 久久久精品国产一区二区三区| 蜜乳av另类精品一区二区| 国产情人综合久久777777| 一区二区动漫| 亚洲高清在线观看一区| 久久激五月天综合精品| 国产精品美女久久久久久久 | 亚洲第一天堂无码专区| 久久久精品动漫| 午夜欧美理论片| 国产免费成人av| 欧美一区二区视频在线观看| 中国成人在线视频| 欧美日韩一区二区三区四区五区| 亚洲精品日产精品乱码不卡| 欧美国产综合| 欧美91大片| 亚洲精品一区二区三区在线观看| 欧美高清视频| 美女国产一区| 亚洲精品乱码久久久久久黑人| 亚洲电影有码| 欧美日韩国产系列| 亚洲男人的天堂在线aⅴ视频| 99亚洲伊人久久精品影院红桃| 欧美日韩在线一区二区| 午夜久久tv| 香蕉国产精品偷在线观看不卡| 国产日韩欧美综合在线| 老司机一区二区| 欧美成人自拍| 在线亚洲+欧美+日本专区| 亚洲欧洲在线视频| 欧美日韩国产一区精品一区| 亚洲一区免费网站| 欧美一区影院| 亚洲国产影院| 亚洲先锋成人| 韩国v欧美v日本v亚洲v | 亚洲毛片在线观看| 国产精品乱人伦中文| 久久婷婷蜜乳一本欲蜜臀| 一区二区三区精品国产| 老色鬼久久亚洲一区二区| 亚洲精品免费在线| 在线日本成人| 性色一区二区| 亚洲一区二三| 欧美色区777第一页| 亚洲国产99精品国自产| 99人久久精品视频最新地址| 极品尤物久久久av免费看| 香蕉久久一区二区不卡无毒影院| 亚洲宅男天堂在线观看无病毒| 欧美精品xxxxbbbb| 亚洲精品久久久一区二区三区| 亚洲精选大片| 激情欧美一区二区三区| 一本色道久久| 亚洲伦理中文字幕| av成人免费| 欧美一级在线视频| 亚洲一区欧美一区| 久久久久一区二区三区四区| 久久精品国产欧美激情| 亚洲精品久久久久久久久久久久久 | 午夜精品久久久久久久99水蜜桃| 欧美成人亚洲| 亚洲社区在线观看| 亚洲国产第一| 国产精品久久久久9999吃药| 欧美日韩视频在线第一区| 亚洲精选中文字幕| 国产亚洲一区二区三区在线播放| 亚洲午夜电影在线观看| 久久精品91| 亚洲视频二区| 亚洲欧美日本国产专区一区| 国产综合自拍| 国产精品久久一级| 欧美精品videossex性护士| 一本色道久久99精品综合| 久久夜色精品国产噜噜av| 亚洲综合精品四区| 欧美一区激情| 一区二区三区福利| 韩曰欧美视频免费观看| 国产精品久久久久久久电影| 欧美福利网址| 免费黄网站欧美| 乱码第一页成人| 久久久久国产精品麻豆ai换脸| 亚洲一区二区三区在线播放| 久久精品色图| 欧美国产一区视频在线观看| 欧美成年人网| 国产伦精品一区二区三区高清版 | 亚洲综合色丁香婷婷六月图片| 久久久精品久久久久| 香蕉亚洲视频| 国产精品一区二区视频 | 亚洲经典三级| 亚洲国产成人精品久久| 久久av一区二区三区漫画| 欧美有码视频| 亚洲一区二区在线观看视频| 99视频日韩| 欧美一区二区三区免费看| 久久综合九色综合欧美就去吻| 蜜臀av性久久久久蜜臀aⅴ| 亚洲高清不卡一区| 玖玖视频精品| 亚洲高清视频的网址| 亚洲免费中文| 欧美电影资源| 国产自产v一区二区三区c| 日韩视频二区| 久久久国产91| 亚洲精品国产精品国自产观看浪潮 | 91久久综合| 亚洲剧情一区二区| 久久一二三四| 日韩午夜电影在线观看| 亚洲精品国产日韩| 欧美在线不卡视频| 一区二区三区鲁丝不卡| 美日韩免费视频| 亚洲高清资源| 午夜日韩电影| 亚洲欧美成人一区二区在线电影| 欧美+亚洲+精品+三区| 久久国产精品一区二区| 99视频有精品| 国产手机视频一区二区| 欧美大秀在线观看 | 美女视频黄免费的久久| 亚洲免费观看在线视频| 国产精品视频网址| 欧美精品在线网站| 久久精品日产第一区二区| 99精品免费视频| 猫咪成人在线观看| 亚洲欧美视频一区| 99av国产精品欲麻豆| 久久国产加勒比精品无码| 国产一区91| 亚洲免费av片| 国产三级精品在线不卡| 老司机一区二区三区| 欧美专区日韩专区|