建体彩网|中彩网双色球连号|
?
快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

和記娛最好h88285愽娛:C++箴言用非成員非友元函數取代成員函數

?

想象一個象征 web 瀏覽器的類。在大年夜量的函數中,這樣一個類大概會供給清空已下載因素的緩存。清空已造訪 URLs 的歷史,以及從系統移除所有 cookies 的功能:

class WebBrowser {

public:

...

void clearCache();

void clearHistory();

void removeCookies();

...

};

很多用戶盼望能一路履行整個這些動作,以是 WebBrowser 可能也會供給一個函數去這樣做:

class WebBrowser {

public:

...

void clearEverything(); // calls clearCache, clearHistory,

// and removeCookies

...

};

當然,這個功能也能經由過程非成員函數調用適當的成員函數來供給:

void clearBrowser(WebBrowser& wb)

{

wb.clearCache();

wb.clearHistory();

wb.removeCookies();

}

那么哪個更好呢和記娛最好h88285愽娛,成員函數 clearEverything 照樣非成員函數 clearBrowser?

面性工具原則指出:數據和對它們進行操作的函數應該被綁定到一路,而且建議成員函數是更好的選擇。不幸的是,這個建議是不精確的。它孕育發生于對面向工具是什么的一個誤解。面向工具原則指出數據應該盡可能被封裝。與直覺不合,成員函數 clearEverything 居然會造成比非成員函數 clearBrowser 更差的封裝性。此外,供給非成員函數容許 WebBrowser 相關功能的更大年夜的包裝彈性,而且,可以得到更少的編譯依附和 WebBrowser 擴展性的增進。因而,在很多方面非成員措施比一個成員函數更好。理解它的緣故原由是異常緊張的。

我們將從封裝開始。假如某物被封裝,它被從視線中暗藏。越多的器械被封裝,就越少有器械能望見它。越少有器和記娛最好h88285愽娛械能望見它,我們改變它的彈性就越大年夜,由于我們的改變僅僅直接影響那些能望見我們變了什么的器械。某物的封裝性越強,那么我們改變它的能力就越強。這便是將封裝的代價評價為第一的緣故原由:它為我們供給一種改變工作的彈性,而僅僅影響有限的客戶。

結合一個工具斟酌數據。越少有代碼能看到數據(也便是說,造訪它),數據封裝性就越強,我們改變工具的數據的特點的自由也就越大年夜,比如,數據成員的數量,它們的類型,等等。作為若干代碼能看到一塊數據的粗拙的尺度,我們可以計數能造訪那塊數據的函數的數量:越多函數能造訪它,數據的封裝性就越弱。

數據成員應該是 private 的,由于假如它們不是,就有無限量的函數能造訪它們。它們根本就沒有封裝。對付 private 數據成員,能造訪他們的函數的數量便是類的成員函數的數量加上友元函數的數量,由于只有成員和友元能造訪 private 成員。假設在一個成員函數(能造訪的不光是一個類的 private 數據,還有 private 函數,羅列,typedefs,等等)和一個供給同樣功能的非成員非友元函數(不能造訪上述那些器械)之間有一個選擇,能得到更強封裝性的選擇長短成員非友元函數,由于它不會增添能造訪類的 private 部分的函數的數量。這就說清楚明了為什么 clearBrowser(非成員非友元函數)比 clearEverything(成員函數)更可取:它能為 WebBrowser 得到更強的封裝性。

在這一點,有兩件事值得留意。首先,這個論證只適用于非成員非友元函數。友元能像成員函數一樣造訪一個類的 private 成員,是以同樣影響封裝。從封裝的不雅點看,選擇不是在成員和非成員函數之間,而是在成員函數和非成員非友元函數之間。(當然,封裝并不是僅有的不雅點,假如不雅點來自隱式類型轉換,選擇便是在成員和非成員函數之間。)

必要留意的第二件事是,假如僅僅是為了關注封裝,則可以指出,一個函數是一個類的非成員并不料味著它弗成所以另一個類的成員。這對付習氣了所有函數必須屬于類的說話(例如,Eiffel,Java,C#,等等)的法度榜樣員是一個適度的勸慰。例如,我們可以使 clearBrowser 成為一個 utility 類的 static 成員函數。只要它不是 WebBrowser 的一部分(或友元),它就不會影響 WebBrowser 的 private 成員的封裝。

在 C++ 中,一個更自然的措施是使 clearBrowser 成為與 WebBrowser 在同一個 namespace(名字空間)中的非成員函數:

namespace WebBrowserStuff {

class WebBrowser { ... };

void clearBrowser(WebBrowser& wb);

...

}

相對付形式上的自然,這樣更適用于它。無論若何,由于名字空間(不像類)能展開到多個源文件中。這是很緊張的,由于類似 clearBrowser 的函數是方便性函數。作為既不是成員也不是友元,他們沒有對 WebBrowser 進行專門的造訪,以是他們不能供給任何一種 WebBrowser 的客戶不能經由過程其它措施獲得的功能。例如,假如 clearBrowser 不存在,客戶可以直接調用 clearCache,clearHistory 和 removeCookies 本身。

一個類似 WebB和記娛最好h88285愽娛rowser 的類可以有大年夜量的方便性函數,一些是書簽相關的,另一些打印相關的,還有一些是 cookie 治理相關的,等等。作為一個一樣平常的常規,多半客戶僅對這些方便性函數的聚攏中的一些感興趣。沒有來由讓一個只對書簽相關的方便性函數感興趣的客戶在編譯時依附其它函數,例如,cookie 相關的方便性函數。分隔它們的刀切斧砍的措施便是在一個頭文件中聲明書簽相關的方便性函數,在另一個不合的頭文件中聲明 cookie 相關的方便性函數,在第三個頭文件聲明打印相關的方便性函數,等等:

// header "webbrowser.h" - header for cl和記娛最好h88285愽娛ass WebBrowser itself

// as well as "core" WebBrowser-related functionality

namespace WebBrowserStuff {

class WebBrowser { ... };

... // "core" related functionality, e.g.

// non-member functions almost

// all clients need

}

// header "webbrowserbookmarks.h"

namespace WebBrowserStuff {

... // bookmark-related convenience

} // functions

// header "w和記娛最好h88285愽娛ebbrowsercookies.h"

namespace WebBrowserStuff {

... // cookie-related convenience

} // functions

...

留意這里就像標準 C++ 庫組織得一樣縝密。勝于有一個零丁的一體式的 <C++StandardLibrary> 頭文件包孕 std namespace 中的所有器械,它們在許多頭文件中(例如,<vector>,<algorithm>,<memory>,等等),每一個都聲清楚明了 std 中的一些性能。僅僅必要 vector 相關性能的客戶不必要 #include <memory>,不用 list 的客戶沒有需要 #include <list>。這就容許客戶在編譯時僅僅依附他們實際應用的那部分系統。當性能來自一個類的成員函數時,用這種措施瓜分它是弗成能的,由于一個類必須作為一個整體來定義,它不能四分五裂。

將所有方便性函數放入多個頭文件中——然則在一個 namespace 中——也意味著客戶能輕易地擴充方便性函數的聚攏。他們必須做的整個便是在 namespace 中加入更多的非成員非友元函數。例如,假如一個 WebBrowser 的客戶抉擇寫一個關于下載圖像的方便性函數,他或她僅僅必要新建一個頭文件,包孕那些函數在 WebBrowserStuff namespace 中的聲明。這個新的函數現在就像其它方便性函數一樣可用并被集成。這是類不能供給的另一個特點,由于類定義對付客戶是擴充封閉的。當然,客戶可以派生新類,然則派生類不能造訪基類中被封裝的(也便是說,private 的)成員,以是這樣的“擴充性能”只有二等身份。此外,不是所有的類都是作為基類設計的。

Things to Remember

用非成員非友元函數取代成員函數。這樣做可以前進封裝性,包裝彈性,和性能擴充性。

免責聲明:以上內容源自網絡,版權歸原作者所有,如有侵犯您的原創版權請告知,我們將盡快刪除相關內容。

您可能還會對下面的文章感興趣:

建体彩网
澳洲幸运10开奖软件app 2019什么手机网游可以赚钱 吉林11选5前三位和值走势图 捷报足球即时赔率 广东快乐十分走势图彩 高频彩追号 p3试机号 pc蛋蛋走势图查询 德甲联赛英文 华东15选5