一篇文章帶你了解C++智能指針詳解_第1頁
一篇文章帶你了解C++智能指針詳解_第2頁
一篇文章帶你了解C++智能指針詳解_第3頁
一篇文章帶你了解C++智能指針詳解_第4頁
一篇文章帶你了解C++智能指針詳解_第5頁
已閱讀5頁,還剩2頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

第一篇文章帶你了解C++智能指針詳解RALL

RALL(ResourceAcquistionIsInitialization)是一種利用對象生命周期來控制程序資源(如內(nèi)存,文件句柄,網(wǎng)絡(luò)連接,互斥量等)的簡單技術(shù)。

在對象構(gòu)造時獲取資源,接著控制對資源的訪問使之在對象的生命周期內(nèi)始終保持有效,最后在對象析構(gòu)的時候釋放資源。相當(dāng)于利用對象管理了一份資源。這樣的優(yōu)勢在于

1.不需要顯式的釋放資源(對象析構(gòu)時,自動釋放資源)

2.采用這種方式,對象所需的資源在其生命周期內(nèi)始終保持有效。

智能指針就是一個實例出來的對象

C++98版本的庫中就提供了auto_ptr的智能指針。但是auto_ptr存在當(dāng)對象拷貝或者賦值之后,前面的對象就懸空了。

C++11提供更靠譜的并且支持拷貝的shared_ptr

shared_ptr:

通過引用計數(shù)的方式實現(xiàn)多個shared_ptr對象之間共享資源。

shared_ptr在其內(nèi)部,給每個資源都維護了著一份計數(shù),用來記錄該份資源被幾個對象共享。在對象被銷毀時(也就是析構(gòu)函數(shù)調(diào)用),就說明自己不使用該資源了,對象的引用計數(shù)減一。如果引用計數(shù)是0,就說明自己是最后一個使用該資源的對象,必須釋放該資源;如果不是0,就說明除了自己還有其他對象在使用該份資源,不能釋放該資源,否則其他對象就成野指針了

unique_ptr:

確保一個對象同一時刻只能被一個智能指針引用,可以轉(zhuǎn)移所有權(quán)(可以從一個智能指針轉(zhuǎn)移到另一個智能指針)

auto_ptr:

C++11已棄用,與unique_ptr類似

使用時,需包含頭文件

#includememory

shared_ptr的使用注意事項

創(chuàng)建

shared_ptrintptr{newint(3)};

shared_ptrintptr;

ptr.reset(newint(3));

shared_ptrintptr=make_sharedint

shared_ptr支持使用比較運算符,使用時,會調(diào)用共享指針內(nèi)部封裝的原始指針的比較運算符。

支持

==、!=、、=、、=

使用比較運算符的前提必須是同類型

示例:

shared_ptrintp1=make_sharedint

shared_ptrintp2=make_sharedint

shared_ptrint

shared_ptrdoublep4=make_shareddouble

boolb1=p1//true

boolb2=p1//true,非NULL指針與NULL指針相比,都是大于

boolb3=p3==p3;//true

boolb4=p4p2//編譯失敗,類型不一致

shared_ptr可以使用強制類型轉(zhuǎn)換,但是不能使用普通的強制類型轉(zhuǎn)換符

1.shared_ptr強制類型轉(zhuǎn)換符允許將其中包含的指針強制轉(zhuǎn)換為其它類型

2.不能使用普通的強制類型轉(zhuǎn)換運算符,否則會導(dǎo)致未定義行為

3.shared_ptr的強制類型轉(zhuǎn)換運算符包括

static_pointer_cast

dynamic_pointer_cast

const_pointer_cast

示例:

shared_ptrvoidp(newint);//內(nèi)部保留void*指針

static_pointer_castint*//正確的強制類型轉(zhuǎn)換方式

shared_ptrintp1(static_castint*(p.get()));//錯誤的強制類型轉(zhuǎn)換方式,未定義錯誤

多個shared_ptr不能擁有同一個對象

利用代碼理解

示例:

classMytest{

public:

Mytest(conststringstr)

:_str(str){}

~Mytest(){

std::cout_str"destory"std::endl;

private:

string_str;

intmain(){

Mytest*p=newMytest("shared_test");

shared_ptrMytestp1(p);//該對象可以正常析構(gòu)

shared_ptrMytestp2(p);//對象銷毀時,錯誤,讀取位置0xDDDDDDDD時發(fā)生訪問沖突。

return0;

上述代碼,共享指針p1對象在程序結(jié)束時,調(diào)用析構(gòu),釋放了p所指向的空間,當(dāng)p2進行析構(gòu)的時候,又釋放p所指向的空間,但是由于已經(jīng)釋放過了,重復(fù)釋放已經(jīng)釋放過的內(nèi)存,導(dǎo)致段錯誤。

可以使用shared_from_this避免這種問題

改進代碼:

classMytest:publicenable_shared_from_thisMytest{

public:

Mytest(conststringstr)

:_str(str){}

~Mytest(){

std::cout_str"destory"std::endl;

shared_ptrMytestGetSharedptr(){

returnshared_from_this();

private:

string_str;

intmain(){

Mytest*p=newMytest("shared_test");

shared_ptrMytestp1(p);

shared_ptrMytestp2=p-GetSharedptr();//正確做法

return0;

shared_ptr的銷毀

shared_ptr在初始化的時候,可以定義刪除器,刪除器可以定義為普通函數(shù)、匿名函數(shù)、函數(shù)指針等符合要求的可調(diào)用對象

示例代碼:

voiddelFun(string*p){

std::cout"Fundelete"*pendl;

deletep;

intmain(){

std::cout"begin"std::endl;

shared_ptrstring

shared_ptrstringp2(newstring("p1"),[](string*p){

std::cout"Lamdadelete"*pstd::endl;

deletep;

p1=p2;

shared_ptrstringp3(newstring("p3"),delFun);

std::cout"end"std::endl;

return0;

執(zhí)行結(jié)果:

begin

Fundeletep3

end

Lamdadeletep1

分析結(jié)果:

首先,p3在{}作用域內(nèi),生命周期最先結(jié)束,調(diào)用delFun作為刪除器

其次,p2也在{}作用域內(nèi),生命周期也結(jié)束了,但是因為p1和p2指向了同一個對象,所以p2銷毀只是將其對象引用計數(shù)-1。

最后,程序運行結(jié)束,p1銷毀,其對象引用計數(shù)-1變?yōu)?,調(diào)用刪除器,銷毀對象。

shared_

溫馨提示

  • 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)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論