




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第C++的智能指針你真的了解嗎目錄什么是RAIIRAII的原理裸指針存在的問題auto_ptrunique_ptr總結(jié)
什么是RAII
RAII(ResourceAcquisitionIsInitialization)是由C++之父提出的,中文翻譯為資源獲取即初始化,使用局部對象來管理資源的技術(shù)稱為資源獲取即初始化;這里的資源主要是指操作系統(tǒng)中有限的東西如內(nèi)存(heap)、網(wǎng)絡(luò)套接字、互斥量、文件句柄等等,局部對象是指存儲在棧的對象,它的生命周期是由操作系統(tǒng)來管理的,無需人工介入
RAII的原理
資源的使用一般經(jīng)歷三個步驟:
獲取資源(創(chuàng)建對象)使用資源銷毀資源(析構(gòu)對象)
但是資源的銷毀往往是程序員經(jīng)常忘記的一個環(huán)節(jié),所以程序界就想如何在程序中讓資源自動銷毀呢?解決問題的方案就是:RAII,它充分的利用了C++語言局部對象自動銷毀的特性來控制資源的生命周期
裸指針存在的問題
1.難以區(qū)分指向的是單個對象還是一個數(shù)組
2.使用完指針之后無法判斷是否應(yīng)該銷毀指針,因為無法判斷指針是否擁有指向的對象
3.在已經(jīng)確定需要銷毀指針的情況下,也無法確定是用delete關(guān)鍵字刪除,還是有其他特殊的銷毀機制,例如通過將指針傳入某個特定的銷毀函數(shù)來摧毀指針
4.即使已經(jīng)確定了銷毀指針的方法,由于1的原因,仍然無法確定到底是i用delete(銷毀單個對象)還是delete[](銷毀一個數(shù)組)
5.假設(shè)上述的問題都解決了,也很難保證在代碼的所有路徑中(分支結(jié)構(gòu),異常導(dǎo)致的挑戰(zhàn)),有且僅有一次銷毀指針的操作;任何一條路徑遺漏都可能導(dǎo)致內(nèi)存的泄露,而銷毀多次則會導(dǎo)致未定義行為
6.理論上沒有方法來分辨一個指針是否處于懸掛狀態(tài)
auto_ptr
classObject
intvalue;
public:
Object(intx=0):value(x)
cout"CreateObject:"thisendl;
~Object()
cout"DestoryObject:"thisendl;
intValue()
returnvalue;
templateclass_Ty
classmy_auto_ptr
private:
bool_Owns;
_Ty*_Ptr;
public:
my_auto_ptr(_Ty*p=NULL):_Owns(p!=NULL),_Ptr(p)
~my_auto_ptr()
if(_Owns)
delete_Ptr;
_Owns=false;
_Ptr=NULL;
voidfun()
my_auto_ptrObjectobj(newObject(10));
intmain()
fun();
在這里將Object構(gòu)建完成后,將其指針給到p,當函數(shù)結(jié)束去調(diào)動智能指針的析構(gòu)函數(shù)去釋放空間
若我們需要在fun()函數(shù)中,去調(diào)用Object類的方法obj-Value();
classObject
intvalue;
public:
Object(intx=0):value(x)
cout"CreateObject:"thisendl;
~Object()
cout"DestoryObject:"thisendl;
intValue()
returnvalue;
templateclass_Ty
classmy_auto_ptr
private:
bool_Owns;
_Ty*_Ptr;
public:
my_auto_ptr(_Ty*p=NULL):_Owns(p!=NULL),_Ptr(p)
~my_auto_ptr()
if(_Owns)
delete_Ptr;
_Owns=false;
_Ptr=NULL;
_Ty*get()const
return_Ptr;
_Tyoperator*()const
return*(get());
_Ty*operator-()const
returnget();
voidfun()
my_auto_ptrObjectobj(newObject(10));
coutobj-Value()endl;
cout(*obj).Value()endl;
intmain()
fun();
通過運算符重載,(*obj)后將直接指向堆區(qū)(heap)的對象實體
若我們通過一個my_auto_ptr去創(chuàng)建另一個my_auto_ptr
classObject
intvalue;
public:
Object(intx=0):value(x)
cout"CreateObject:"thisendl;
~Object()
cout"DestoryObject:"thisendl;
intValue()
returnvalue;
templateclass_Ty
classmy_auto_ptr
private:
bool_Owns;
_Ty*_Ptr;
public:
my_auto_ptr(_Ty*p=NULL):_Owns(p!=NULL),_Ptr(p)
~my_auto_ptr()
if(_Owns)
delete_Ptr;
_Owns=false;
_Ptr=NULL;
my_auto_ptr(constmy_auto_ptrobj):_Owns(obj._Owns),_Ptr(obj._ptr)
my_auto_ptroperator=(constmy_auto_ptr_Y)
if(this==_Y)return*this;
if(_Owns)
delete_Ptr;
_Owns=_Y._Owns;
_Ptr=_Y._Ptr;
return0;
_Ty*get()const
return_Ptr;
_Tyoperator*()const
return*(get());
_Ty*operator-()const
returnget();
voidreset(_Ty*p=NULL)
if(_Owns)
delete_Ptr;
_Ptr=p;
_Ty*release()const
_Ty*tmp=NULL;
if(_Owns)
((my_auto_ptr*)this)-_Owns=false;//常性進行修改
tmp=_Ptr;
((my_auto_ptr*)this)-_Ptr=NULL;
returntmp;
voidfun()
my_auto_ptrObjectpobja(newObject(10));
my_auto_ptrObjectpobjb(pobja);
intmain()
fun();
如果通過淺拷貝,則兩個指針擁有同一個資源,在析構(gòu)的過程會造成資源的重復(fù)釋放導(dǎo)致崩潰
若設(shè)置為將其資源進行轉(zhuǎn)移
my_auto_ptr(constmy_auto_ptrobj):_Owns(obj._Owns),_Ptr(release())
my_auto_ptroperator=(constmy_auto_ptr_Y)
if(this==_Y)return*this;
if(_Owns)
delete_Ptr;
_Owns=_Y._Owns;
_Ptr=_Y.release();
return0;
voidfun(my_auto_ptrObjectapx)
intx=apx-Value();
coutxendl;
intmain()
my_auto_ptrObjectpobja(newObject(10));
fun(pobja);
inta=pobja-Value();
coutaendl;
那么上面的過程中,資源會進行轉(zhuǎn)移pobja將不再擁有資源,導(dǎo)致pobja失去資源進而程序崩潰
這也就是auto_ptr的局限性,也導(dǎo)致該智能指針的幾乎沒有使用
unique_ptr
該智能指針屬于唯一性智能指針,將拷貝構(gòu)造刪除,也就不能將其新建另一個對象,同時也不能作為參數(shù)傳入
classObject
intvalue;
public:
Object(intx=0):value(x)
cout"CreateObject:"thisendl;
~Object()
cout"DestoryObject:"thisendl;
intValue()
returnvalue;
intmain()
std::unique_ptrObjectpobja(newObject(10));
//std::unique_ptrObjectpobjb(pobja);error
//不允許
std::unique_ptrObjectpobjb(std::move(pobja));
通過移動賦值是可以的,通過明確的概念,對其資源進行轉(zhuǎn)移
同時unique_ptr可以區(qū)分其所指向的是一個單獨空間,或者是連續(xù)的空間
structdelete_ar_object
voidoperator()(Object*op)
if(op==NULL)return;
delete[]op;
intmain()
std::unique_ptrObjectpobja(newObject(10));
std::unique_ptrObject,delete_ar_objectpobjb(newObject[10]);
在這里如果是連續(xù)空間,會調(diào)用刪除連續(xù)空間的刪除器;單獨空間則使用默認刪除器
unique_ptr在編寫的時候,有多個模板類,分別對應(yīng)單個對象的方案和一組對象的方案
并且可以通過智能指針指向fopen打開的文件對象,而文件對象是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- T/CNFA 9-2019中式家具常用木材識別
- T/CIMA 0032-2022單相智能電能表設(shè)計方案多目標穩(wěn)健性評價通則
- T/CHASA 001-2018凈水上門服務(wù)工程師資質(zhì)認證規(guī)范
- T/CECS 10349-2023綠色校園用裝飾裝修材料抗菌、抗病毒性能要求
- T/CECS 10109-2020耐腐蝕預(yù)制混凝土樁
- T/CCMA 0168-2023土方機械電控手柄技術(shù)要求及試驗方法
- T/CCMA 0095-2020非公路自卸車操作使用規(guī)程
- T/CCAS 021-2021水泥生料助磨劑
- T/CCAS 004-2018錳(礦)渣化學(xué)分析方法
- T/CAQI 86-2019家用和類似用途新風(fēng)機空氣清新度技術(shù)要求及試驗方法
- 現(xiàn)場照相技術(shù)課件
- 抖音帶貨主播勞動合同范本
- 廣東省高等學(xué)校“千百十工程”第六批繼續(xù)培養(yǎng)對象和第
- 人教版三年級數(shù)學(xué)上冊口算題卡
- 綠色施工與環(huán)境管理
- 小數(shù)乘整數(shù)的教學(xué)設(shè)計 小數(shù)乘整數(shù)教學(xué)設(shè)計一等獎(十四篇)
- 畢業(yè)設(shè)計基于單片機的發(fā)動機轉(zhuǎn)速電控系統(tǒng)程序設(shè)計及仿真
- 統(tǒng)借統(tǒng)還資金分撥合同
- 地鐵運營施工負責(zé)人考試題庫
- GB/T 708-2006冷軋鋼板和鋼帶的尺寸、外形、重量及允許偏差
- 故宮的資料簡介(標準版)
評論
0/150
提交評論