C++的智能指針你真的了解嗎_第1頁
C++的智能指針你真的了解嗎_第2頁
C++的智能指針你真的了解嗎_第3頁
C++的智能指針你真的了解嗎_第4頁
C++的智能指針你真的了解嗎_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論