C C 避坑經驗談 資源管理類 智慧型指標

2021-07-25 05:57:59 字數 1937 閱讀 9774

前面提到,c++中盡量不要使用指標。在**量變得很高的情況下,程式猿很容易錯誤使用指標。為此,我們可以利用c++的類和智慧型指標來管理資源。這兩者是相輔相成的。他們稱為raii技術。

一、如何設計資源管理類?

《effective c++》這本書的類那一章,告訴我們很多設計類的方法。對於資源管理類,我們讀到的準則是,將資源管理類設計得猶如int整型一樣。

int整形資料有這些特徵:

退出作用域就銷毀。這僅僅需要編寫乙個優秀的析構函式,必須注意釋放所有資源。有時候資源管理類太大,銷毀的代價很高,我們會希望能夠重複使用。然而,我們不能因為有這個需求就改變「資源管理類退出作用域就銷毀」這個原則。替代方法有重寫記憶體池,使用智慧型指標包裹資源管理類。

二、什麼時候使用智慧型指標?

不僅在某個作用域發揮作用,而是要在程式中很多地方發揮作用的資源,需要用智慧型指標來包裝。如果只是臨時使用,用資源管理類完全ok,直接用指標都可以。

智慧型指標一般用來包裹資源管理類。資源管理類可以有效遏制資源洩露、濫用資源的問題,其超出作用域即銷毀。如果不想讓資源管理類銷毀,想把它用到其他地方,就用智慧型指標包裹。智慧型指標的好處是,如果沒有地方引用智慧型指標,智慧型指標就連帶資源管理類銷毀。例如:

//ptr被a引用了,ptr被銷毀,但是指向的資源不會銷毀

std::shared_ptr

}//最後的引用a被銷毀。資源的引用數為0,被銷毀。

三、智慧型指標可能有什麼問題?

智慧型指標並不是指標,而是行為表現像指標的類。其內部有乙個指向真正資源的成員變數和乙個記錄被引用次數的計數器。

指標是指向資料存放位址的資料。c++編譯器通過靈活解釋指標,來實現c++類的多型特性。譬如有父類superclass和子類derivedclass,父類指標可以指向子類指標,在處理指向子類的父類指標的行為時,編譯器認為這是乙個superclass指標,只會搜尋superclass的定義範圍,從而行為上只能表現出superclass才有的行為;如果用dynamic_cast將父類指標轉換為子類指標,在處理指向子類的父類指標的行為時,編譯器認為這是乙個derivedclass指標,會搜尋derivedclass的定義範圍,然而指標還是那個指標。

我們按照引用計數的方法自己製作的智慧型指標是不具有多型性的。因為它只是乙個類。

在新版本c++中,智慧型指標使用複雜的模板技術實現了「多型性」,跟普通指標行為驚人地相似:

#include 

#include

struct superclass

};struct derivedclass:public superclass

};void foo1(superclass *p)

void foo2(std::shared_ptr

p)int main(void)

輸出為四個derived。標準庫的智慧型指標實現了多型性,我們應該使用標準庫的智慧型指標。自己造輪子吃力不討好。

還可以通過dynamic_pointer_cast來顯式獲取指向多型型別的智慧型指標,例如:

std:

:shared_ptr d = ...;//定義

std:

:shared_ptr s = std:

:dynamic_pointer_cast(d);

智慧型指標建議不要包裹除了資源管理類以外的物件。比如std::shared_ptra = std::shared_ptr(new int[5]);是錯誤用法。替代方法是使用std::shared_array,但是這個是固定長度的陣列,還不如用std::shared_ptr>。vector本身可以看做對動態長度陣列的包裝。

std::shared_ptr在迴圈引用時會遇到問題,參見【c++】c++避坑經驗談:陣列、vector。

跳槽經驗談

每年年初跳槽最多,跳槽是一門學問,也是一種策略。跳槽並不意味著你就能夠取得職業的成功,當面臨跳槽時,如何順利地完成跳槽,從而取得職業的成功呢?以下是一些切身體會,值得大家參考。1 不要指望會一下子能夠跳到多麼好的公司,絕大多數公司都乙個樣子。比如用友 金蝶 亞信 神馬這些公司,其實基本上乙個樣子。2...

程式設計經驗談

不知不覺做軟體已經做了十年,有成功的喜悅,也有失敗的痛苦,但總不敢稱自己是高手,因為和我心目中真正的高手們比起來,還差的太遠。世界上並沒有成為高手的捷徑,但一些基本原則是可以遵循的。紮實的基礎。資料結構 離散數學 編譯原理,這些是所有電腦科學的基礎,如果不掌握他們,很難寫出高水平的程式。據我的觀察,...

程式設計經驗談

1 萬丈高樓平地起。基礎是一切技能的本源,只有打好基礎,才能談得上提高,才能談得上有靈感,有突破。2 書上學的終覺淺。程式設計是一門實踐性極強的工作,只有通過不斷的程式設計實踐,才能積累程式設計經驗 提高程式設計能力,才能真正成為一名合格的開發者。3 曲徑通幽處。學習程式設計的道路是充滿艱辛的,漫長...