今天,我們討論了使用的功能返回乙個指向下乙個潛在的錯誤。如果有乙個函式返回乙個指標myclass物件的指標型別。
myclass* myfactoryclass::create(const inputs& inputs);
這個函式的乙個非常顯而易見的問題是。它的呼叫者是否負責刪除這個物件?或者說這個指標所指向的myclass類的例項是myfactoryclass所擁有的例項?這個問題顯然應該在宣告這個函式的標頭檔案裡以凝視的形式說明。但在軟體的世界裡,實際上非常少可以做到這樣。
可是。即使函式的作者確實提供了乙個凝視。表示這個函式在堆上建立了乙個新物件,而且由它的呼叫者負責刪除這個物件,我們將會發現自己面臨這樣一種處境:每當我們接到乙個由函式呼叫所返回的指向某個物件的指標時,我們須要記得檢查凝視(或者在沒有凝視時,檢查**本身)來判斷是否由我們負責刪除這個物件。
正如前面所說的,我們應該很多其它地依賴編譯器而不是程式猿。因此。實行這個物件全部權的一種可靠方法是讓函式返回乙個智慧型指標。
比如:
refcountptrmyfactoryclass::create(const inputs& inputs);
這樣的設計使函式所返回的物件的全部權毫無爭議,不會留下記憶體洩露的機會。還有一方面,假設認為引用計數指標速度過慢不適合須要,也能夠返回乙個作用域指標。但這樣就產生了乙個問題:scopedptr無法被複製。因此不能依照傳統方法返回:
scopedptrmyfactoryclass::create(const inputs& inputs)
因此,解決問題的方法例如以下:
scopedptrresult;//建立乙個空的作用域指標
//填充它
void myfactoryclass::create(const inputs& inputs,scopedptr& result);
我們建立乙個包括null值的作用域指標。並讓myfactoryclass::create()方法填充他。
這種方法也不會使這個函式所建立的物件的全部權出現錯誤。假設不確定應該返回哪種指標,能夠選擇下列方案之中的乙個:
另一種相反的情況是,someclass::find()方法返回乙個指向乙個物件的指標,但使用者並不擁有這個物件的全部權:
//返回乙個指向乙個結果的指標,呼叫者「並不擁有這個結果的全部權」
myclass* someclass::find(const inputs& inputs);
這樣的情況下,這個函式所返回的指標,指向屬於someclass內部的某個物件的乙個物件。
對於上述第乙個問題,someclass類覺得自己將負責刪除它剛返回的那個指標所指向的myclass例項。因此會在未來的某個時刻將它刪除。
在這樣的情況下。假設這個函式的使用者將刪除他所接收到的指標。這個例項將被刪除不止一次。這顯然不是個好主意。其次,這個例項可能是乙個vector模板中使用new操作符(帶方括號)建立的乙個myclass物件陣列的一部分,而如今我們將使用不帶方括號的delete操作符從這個陣列中刪除乙個物件。
這相同不是個好的做法。最後,myclass例項可能是在堆疊上建立的,根本不應該使用delete操作符進行刪除。
在這樣的情況下,不論什麼試圖刪除我們並不擁有的物件的行為(直接刪除。或者把它賦值給乙個將接收物件全部權的不論什麼型別的智慧型指標)將會導致災難。
返回這樣的指標的一種合適的方法是返回乙個」半智慧型「指標,它並不擁有它所指向的物件的全部權。
總結:為了避免記憶體洩露,建議遵從下面規則:
指標(4)智慧型指標的使用
why shared ptr 1 如果指標作為類成員時,使用shared ptr封裝原始指標,解決了複製類物件出現的問題 相較原始指標 如果是非記憶體資源 比如 互斥器 可以在構造時再傳乙個刪除器 deleter 引數 shared ptr可以,auto ptr不能 因為shared ptr預設行為...
C 智慧型指標的使用
測試環境 win7,vs2012 如果未安裝boost,請參考 涉及智慧型指標 shared ptr,weak ptr,scoped ptr,auto ptr 其它 enable shared from this 總呼叫函式 testsmartpointer 可以將其放在main 中執行。解釋在 中...
C 智慧型指標的使用
c 11中提供了三種智慧型指標 unique ptr shared ptr weak ptr 來自動 堆分配的物件。unique ptr如它的名字所傳達的意思,其所指向的記憶體區不能與unique ptr定義的另乙個指標共享。看 比較容易理解。include include using namesp...