進(jìn)行C++標(biāo)準(zhǔn)模板庫管理
C++標(biāo)準(zhǔn)模板庫是由Alexander Stepanov、Meng Lee和David R Musser在惠普實(shí)驗(yàn)室工作時(shí)所開發(fā)出來的,C++標(biāo)準(zhǔn)模板庫在C++中的應(yīng)用十分廣泛,這項(xiàng)技術(shù)在引進(jìn)C++之前已經(jīng)使用很久了。
我們會(huì)假設(shè)一個(gè)失敗的資源分配會(huì)導(dǎo)致一個(gè)異常--事實(shí)上,這會(huì)經(jīng)常的發(fā)生。所以如果你想試圖用一個(gè)石頭打兩只鳥的話,或者在一個(gè)構(gòu)造函數(shù)中申請(qǐng)兩種形式的資源,你可能就會(huì)陷入麻煩。
只要想想在一種資源分配成功但另一種失敗拋出異常時(shí)會(huì)發(fā)生什么。因?yàn)闃?gòu)造函數(shù)還沒有全部完成,析構(gòu)函數(shù)不可能被調(diào)用,第一種資源就會(huì)發(fā)生泄露。這種情況可以非常簡單的避免。無論何時(shí)你有一個(gè)需要兩種以上資源的類時(shí),寫兩個(gè)笑的封裝器將它們嵌入你的類中。每一個(gè)嵌入的構(gòu)造都可以保證刪除,即使包裝類沒有構(gòu)造完成。
我們至今還沒有討論最常見類型的資源--用操作符new分配,此后用指針訪問的一個(gè)對(duì)象。我們需要為每個(gè)對(duì)象分別定義一個(gè)封裝類嗎?(事實(shí)上,C++標(biāo)準(zhǔn)模板庫已經(jīng)有了一個(gè)模板類,叫做auto_ptr,其作用就是提供這種封裝。我們一會(huì)兒在回到auto_ptr。)讓我們從一個(gè)極其簡單、呆板但安全的東西開始??聪旅娴腟mart Pointer模板類,它十分堅(jiān)固,甚至無法實(shí)現(xiàn)。
- class Lock
- {
- public:
- Lock (CritSect& critSect)
- : _critSect (critSect)
- {
- _critSect.Acquire ();
- }
- ~Lock ()
- {
- _critSect.Release ();
- }
- private
- CritSect & _critSect;
- };
- 鎖一般的用法如下:
- void Shared::Act () throw (char *)
- {
- Lock lock (_critSect);
- // perform action -- may throw
- // automatic destructor of lock
- }
為什么要把SPtr的構(gòu)造函數(shù)設(shè)計(jì)為protected呢?如果我需要遵守第一條規(guī)則,那么我就必須這樣做。資源--在這里是class T的一個(gè)對(duì)象--必須在封裝器的構(gòu)造函數(shù)中分配。但是我不能只簡單的調(diào)用new T,因?yàn)槲也恢繲的構(gòu)造函數(shù)的參數(shù)。
因?yàn)?,在原則上,每一個(gè)T都有一個(gè)不同的構(gòu)造函數(shù);我需要為他定義個(gè)另外一個(gè)封裝器。C++標(biāo)準(zhǔn)模板庫的用處會(huì)很大,為每一個(gè)新的類,我可以通過繼承SPtr定義一個(gè)新的封裝器,并且提供一個(gè)特定的構(gòu)造函數(shù)。
同樣的,你也可以再你的代碼中用加強(qiáng)Release的可靠性。相應(yīng)的Pop方法要做些什么呢?他應(yīng)該釋放了資源并祈禱調(diào)用它的是一個(gè)負(fù)責(zé)的人而且立即作一個(gè)資源傳遞它到一個(gè)Smart Pointer?這聽起來并不好。
資源管理在內(nèi)容索引(Windows NT Server上的一部分,現(xiàn)在是Windows 2000)上工作,并且,我對(duì)這十分滿意。然后我開始想……這一方法是在這樣一個(gè)完整的系統(tǒng)中形成的,如果可以把它內(nèi)建入語言的本身豈不是一件非常好?我提出了強(qiáng)指針(Strong Pointer)和弱指針(Weak Pointer)。
一個(gè)Strong Pointer會(huì)在許多地方和我們這個(gè)SPtr相似--它在超出它的作用域后會(huì)清除他所指向的對(duì)象。資源傳遞會(huì)以強(qiáng)指針賦值的形式進(jìn)行。也可以有Weak Pointer存在,它們用來訪問對(duì)象而不需要所有對(duì)象--比如可賦值的引用。
任何C++標(biāo)準(zhǔn)模板庫都必須聲明為Strong或者Weak,并且語言應(yīng)該來關(guān)注類型轉(zhuǎn)換的規(guī)定。例如,你不可以將Weak Pointer傳遞到一個(gè)需要Strong Pointer的地方,但是相反卻可以。Push方法可以接受一個(gè)Strong Pointer并且將它轉(zhuǎn)移到Stack中的Strong Pointer的序列中。Pop方法將會(huì)返回一個(gè)Strong Pointer。把Strong Pointer的引入語言將會(huì)使垃圾回收成為歷史。
【編輯推薦】