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

Shuffy

不斷的學習,不斷的思考,才能不斷的進步.Let's do better together!
posts - 102, comments - 43, trackbacks - 0, articles - 19
[轉]http://m.shnenglu.com/tiandejian/archive/2007/05/13/cp_15.html

第15條:     要為資源管理類提供對原始資源的訪問權

資源管理類的特征是振奮人心的。它構筑起可靠的屏障,有效地防止你的程序發(fā)生資源泄漏。對于一個系統的設計方案是否優(yōu)異,能否預防這樣的泄漏可作為一個基本評判標準。在完美的世界里,你可以依靠資源管理類來完成所有的與資源交互的工作,你永遠也不能直接訪問原始資源。然而世界并不是完美的。許多 API 會直接引用資源,所以除非你發(fā)誓不使用這樣的 API (這樣做顯得太不實際了),否則,你必須繞過資源管理類,然后在需要的時候及時手工處理原始資源。

舉例說,第 13 條中引入了下面的做法 :使用諸如 auto_ptr 或者 tr1::shared_ptr 這樣的智能指針來保存諸如 createInvestment 這樣的工廠函數的返回值:

std::tr1::shared_ptr<Investment> pInv(createInvestment());

                                       // 來自第 13

假設,當你使用一個 Investment 對象時,你需要一個這樣的函數:

int daysHeld(const Investment *pi);    // 返回投資持續(xù)的天數

你可能希望這樣來調用它:

int days = daysHeld(pInv);             // 錯!

但是這段代碼無法通過編譯:因為 daysHeld 需要一個原始的 Investment* 指針,但是你傳遞給它的對象的類型卻是 tr1::shared_ptr<Investment>

你需要一個渠道來 將一個 RAII 類的對 象(在上面的示例中是 tr1::shared_ptr )轉變?yōu)樗脑假Y源(比如說,原始的 Investment* )。這里實現這一轉變有兩個一般的方法:顯式轉換和隱式轉換。

tr1::shared_ptr auto_ptr 都提供了一個 get 成員函數來進行顯式轉換,也就是說,返回一個智能指針對象中的裸指針(的副本):

int days = daysHeld(pInv.get());       // 工作正常,將 pInv 中的

                                       // 裸指針傳遞給 daysHeld

似乎所有的智能指針類,包括 tr1::shared_ptr auto_ptr 等等,都會重載指針解析運算符( operator-> operator* ),這便使得對原始裸指針進行隱式轉換成為現實:

class Investment {                 // 投資類型的層次結構中

                                   // 最為根基的部分

public:

 bool isTaxFree() const;

 ...

};

 

Investment* createInvestment();    // 工廠函數

 

std::tr1::shared_ptr<Investment> pi1(createInvestment());

                                   // 使用 tr1::shared_ptr

                                   // 管理資源

bool taxable1 = !(pi1->isTaxFree());

                                   // 通過 operator-> 訪問資源

...

 

std::auto_ptr<Investment> pi2(createInvestment());

                                   // 使用 auto_ptr 管理資源

bool taxable2 = !((*pi2).isTaxFree());

                                   // 通過 operator* 訪問資源

...

由于 某些時刻你需要獲取一個 RAII 對象中的原始資源,所以一些 RAII 類的設計者使用了一個小手段來使系統正常運行,那就是:提供一個隱式轉換函數。舉例說,以下是一個 C 語言 API 中提供的處理字體的一個 RAII 類:

FontHandle getFont();              // 來自一個 C 語言 API

                                   // 省略參數表以簡化代碼

 

void releaseFont(FontHandle fh);   // 來自同一個 C 語言 API

 

class Font {                       // RAII

public:

 explicit Font(FontHandle fh)     // 通過傳值獲取資源

 : f(fh)                          // 因為這一 C 語言 API 這樣做

 {}

 

 ~Font() { releaseFont(f); }      // 釋放資源

 

private:

 FontHandle f;                        // 原始的字體資源

};

假設這里有一個大型的相關的 C 語言 API 僅僅通過 FontHandle 解決字體問題,那么將存在十分頻繁的把 Font 對象轉換為 FontHandle 的操作。 Font 類可以提供一個顯式轉換函數,比如 get

class Font {

public:

 ...

 FontHandle get() const { return f; }

                                   // 進行顯式轉換的函數

 ...

};

遺憾的是,這樣做使得客戶端程序員在每次 與這一 API 信時都要調用一次 get

void changeFontSize(FontHandle f, int newSize);

                                   // 來自一個 C 語言 API

Font f(getFont());

int newFontSize;

...

 

changeFontSize(f.get(), newFontSize);

                                   // 顯式轉換:從 Font FontHandle

由于需要顯式請求這樣的轉換,這樣做顯得得不償失,一些程序員也許會拒絕使用這個類。然而這又增加了字體資源泄漏的可能性,這與 Font 類的設計初衷是完全相悖的。

有一個替代方案,讓 Font 提供一個將其隱式轉換為 Fonthandle 的函數:

class Font {

public:

 ...

 operator FontHandle() const { return f; }

                                   // 進行隱式轉換的函數

 

 ...

};

這使得調用這一 C 語言 API 的工作變得簡潔而且自然:

Font f(getFont());

int newFontSize;

...

 

changeFontSize(f, newFontSize);    // 隱式轉換:從 Font FontHandle

 

隱式轉換會帶來一定的負面效應:它會增加出錯的可能。比如說,一個客戶端程序員在一個需要 Font 的地方意外地創(chuàng)建了一個 FontHandle

Font f1(getFont());

...

FontHandle f2 = f1;                // 啊哦!本想復制一個 Font 對象,

                                   // 但是卻卻將 f1 隱式轉換為其原始的

                                   // FontHandle ,然后復制它

現在程序中有一個 FontHandle 資源正在由 Font 對象 f1 來管理,但是仍然可以通過 f2 直接訪問 FontHandle 資源。這是很糟糕的。比如說,當 f1 被銷毀時,字體就會被釋放, f2 也一樣。

RAII 類提供顯式轉換為其原始資源的方法,還是允許隱式轉換,上面兩個問題的答案取決于 RAII 類設計用于完成的具體任務,及其被使用的具體環(huán)境。最好的設計方案應該遵循第 18 的建議,讓接口更容易被正確使用,而不易被誤用。通常情況下,定義一個類似于 get 的顯式轉換函數是一個較好的途徑,應為它可以使非故意類型轉換的可能性降至最低。然而,使用隱式類型轉換顯得更加自然,人們更趨向于使用它。

你可能已經發(fā)現,讓一個函數返 回一個 RAII 類內部的原始資源是違背封裝性原則的。的確是這樣,但是它實際上并不像看上去那樣糟糕。 RAII 類并不是用來封裝什么的。它們是用來進行一些特別的操作的,那就是資源釋放。如果需要,資源封裝工作可以放在這一主要功能的最頂端,但是這并不是必需的。另外,一 RAII 結合了實現封裝的嚴格性和原始資源封裝的寬松性。比如 tr1::shared_ptr 對其引用計數機制進行了整體封裝,但是它仍然為其所包含的裸指針提供了方便的訪問方法。就像其它設計優(yōu)秀的類一樣,它隱藏了客戶端程序員不需要關心的內容,但是它使得客戶端程序員的確需要使用的部分對其可見。

牢記在心

API 通常需要訪問原始資源,因此每個 RAII 類都應該提供一個途徑來獲取它所管理的資源。

訪問可以通過顯式轉換或隱式轉換來實現。一般情況下,顯式轉換更安全,但是隱式轉換對于客戶端程序員來說使用更方便。

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            国内精品久久久久久久影视麻豆| 亚洲国产另类 国产精品国产免费| 国产伦精品一区二区三区免费| 欧美激情一区二区三区 | 久久中文字幕导航| 久久九九有精品国产23| 久久婷婷av| 最近看过的日韩成人| 日韩午夜视频在线观看| 亚洲淫片在线视频| 久久频这里精品99香蕉| 欧美激情va永久在线播放| 欧美午夜精品理论片a级大开眼界| 国产日韩精品在线播放| 在线亚洲国产精品网站| 亚洲欧美日韩精品久久久| 亚洲视频久久| 久久久精品网| 亚洲福利在线看| 亚洲一区www| 久久综合给合| 欧美午夜在线一二页| 国产原创一区二区| 一区二区三区久久网| 久久精品国产亚洲高清剧情介绍| 亚洲成人在线视频播放 | 亚洲欧美资源在线| 另类人畜视频在线| 国产精品一区二区在线| 亚洲人精品午夜| 久久久精品一品道一区| 日韩视频在线观看| 久久人人97超碰国产公开结果| 欧美视频在线观看 亚洲欧| 国产一区二区日韩| 国产精品99久久99久久久二8| 久久精品二区亚洲w码| 亚洲人成7777| 久久婷婷色综合| 国产欧美婷婷中文| 一区二区三区产品免费精品久久75| 久久精品国产69国产精品亚洲| 亚洲欧洲美洲综合色网| 久久久久久久高潮| 国产日韩在线看片| 亚洲女同在线| 亚洲乱亚洲高清| 嫩草影视亚洲| 亚洲电影激情视频网站| 久久天天躁狠狠躁夜夜av| 亚洲欧美久久久| 国产精品日韩一区| 亚洲一区二区三区四区中文| 最新中文字幕一区二区三区| 久久亚洲视频| 亚洲电影免费在线观看| 久久夜色精品国产欧美乱极品 | 久久久欧美一区二区| 国产欧美一区二区三区在线看蜜臀| 一区二区91| 亚洲精品日日夜夜| 欧美激情按摩在线| 欧美好骚综合网| 久久国产高清| 麻豆成人av| 欧美一区二区三区精品电影| 亚洲欧美文学| 国产欧美精品日韩精品| 亚洲在线中文字幕| 99re这里只有精品6| 欧美日韩国产精品一区二区亚洲| 亚洲激情在线观看视频免费| 免费永久网站黄欧美| 美女精品视频一区| 99精品国产一区二区青青牛奶 | 日韩视频在线一区二区| 欧美国产欧美综合| 一区二区三区精品视频在线观看| 日韩一二三在线视频播| 国产精品国产三级国产aⅴ浪潮 | 99pao成人国产永久免费视频| 欧美日韩国产在线播放网站| 99视频超级精品| 亚洲网在线观看| 国产一区二区三区久久| 欧美不卡在线| 欧美啪啪一区| 性xx色xx综合久久久xx| 久久国产66| 亚洲精品美女在线| 日韩亚洲精品电影| 国产欧美日韩亚洲一区二区三区| 久久久亚洲影院你懂的| 巨乳诱惑日韩免费av| 一本色道婷婷久久欧美| 亚洲免费在线精品一区| 亚洲国产婷婷| 香蕉尹人综合在线观看| 亚洲欧洲精品一区二区三区不卡 | 亚洲欧美国产高清| 久久精品国产免费观看| 99爱精品视频| 亚洲国产精品成人精品| 国产精品五月天| 欧美成人在线网站| 国产精品一区久久久| 欧美激情视频网站| 国产精品免费区二区三区观看| 久热国产精品视频| 国产精品天美传媒入口| 亚洲国产精品一区在线观看不卡| 国产精品视频免费| 亚洲乱码一区二区| 在线精品亚洲| 欧美一区二区三区久久精品茉莉花 | 欧美激情一区二区三区全黄| 欧美一区中文字幕| 欧美大胆成人| 狠狠狠色丁香婷婷综合激情| 一本到高清视频免费精品| 有坂深雪在线一区| 亚洲欧美日韩一区在线观看| 中文日韩欧美| 欧美电影在线观看完整版| 久久性天堂网| 国产在线一区二区三区四区 | 亚洲美女毛片| 亚洲人体一区| 老司机凹凸av亚洲导航| 久久久国产一区二区| 国产精品国产三级国产aⅴ无密码| 欧美高清在线一区二区| 激情欧美一区二区三区| 午夜欧美电影在线观看| 亚洲欧美影院| 国产精品久久久久久久一区探花| 亚洲麻豆av| 99视频一区二区三区| 欧美激情精品久久久久久大尺度| 欧美激情2020午夜免费观看| 在线播放日韩专区| 欧美在线精品一区| 久久精品免费| 国产最新精品精品你懂的| 午夜国产一区| 久久美女性网| 伊人蜜桃色噜噜激情综合| 欧美在线播放一区| 久久综合电影| 亚洲高清二区| 欧美精品高清视频| 亚洲精品在线视频| 亚洲综合视频在线| 国产欧美一区二区三区在线老狼| 午夜精品久久久久久久99黑人| 香蕉视频成人在线观看| 国产日韩欧美成人| 老司机成人在线视频| 亚洲国产精品成人va在线观看| 99成人精品| 国产伦精品一区二区| 久久成年人视频| 欧美激情亚洲自拍| 亚洲自拍偷拍福利| 国产亚洲午夜| 欧美成人精品在线视频| 日韩视频一区二区三区在线播放 | 免费成人高清| 99亚洲精品| 国产精品丝袜白浆摸在线| 欧美伊人久久| 亚洲人成啪啪网站| 午夜精品久久久久久久男人的天堂 | 欧美精品日韩精品| 欧美日韩国产成人在线观看| 国产精品99久久不卡二区| 久久精品日韩| 日韩视频免费观看高清完整版| 欧美视频在线视频| 久久精品国产77777蜜臀 | 美女网站在线免费欧美精品| 免费精品99久久国产综合精品| 亚洲三级色网| 久久久久久网| 亚洲一级二级在线| 1204国产成人精品视频| 欧美日韩精品免费观看视频完整| 午夜精品视频在线观看| 亚洲欧洲日韩综合二区| 久久精品国产第一区二区三区| 亚洲激情偷拍| 国产真实乱偷精品视频免| 欧美精品综合| 亚洲国产精品一区二区www在线| 久久国产成人| 亚洲一区免费网站| 亚洲毛片在线| 在线观看成人小视频| 国产精品视频一二三| 欧美日韩第一区|