一文掌握C++ 智能指針全部用法_第1頁
一文掌握C++ 智能指針全部用法_第2頁
一文掌握C++ 智能指針全部用法_第3頁
一文掌握C++ 智能指針全部用法_第4頁
一文掌握C++ 智能指針全部用法_第5頁
已閱讀5頁,還剩4頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第一文掌握C++智能指針全部用法//unique_ptrTup1(newT());定義unique_ptr,同時(shí)指向類型為T的對象

unique_ptrTestt2(newTest);

//unique_ptrT[]空的unique_ptr,可以指向類型為T[的數(shù)組對象

unique_ptrint[]

//unique_ptrT[]up1(newT[]);定義unique_ptr,同時(shí)指向類型為T的數(shù)組對象

unique_ptrint[]t4(newint[5]);

//unique_ptrT,Dup();空的unique_ptr,接受一個(gè)D類型的刪除器D,使用D釋放內(nèi)存

unique_ptrTest,DestructTest

//unique_ptrT,Dup(newT());定義unique_ptr,同時(shí)指向類型為T的對象,接受一個(gè)D類型的刪除器D,使用刪除器D來釋放內(nèi)存

unique_ptrTest,DestructTestt6(newTest);

賦值

unique_ptrTestt7(newTest);

unique_ptrTestt8(newTest);

t7=std::move(t8);//必須使用移動語義,結(jié)果,t7的內(nèi)存釋放,t8的內(nèi)存交給t7管理

t7-doSomething();

主動釋放對象

unique_ptrTestt9(newTest);

t9=NULL;

t9=nullptr;

t9.reset();

放棄對象的控制權(quán)

Test*t10=t9.release();

重置

t9.reset(newTest);

auto_ptr與unique_ptr智能指針的內(nèi)存管理陷阱

auto_ptrstring

string*str=newstring("智能指針的內(nèi)存管理陷阱");

p1.reset(str);//p1托管str指針

auto_ptrstring

p2.reset(str);//p2接管str指針時(shí),會先取消p1的托管,然后再對str的托管

//此時(shí)p1已經(jīng)沒有托管內(nèi)容指針了,為NULL,在使用它就會內(nèi)存報(bào)錯(cuò)!

cout"str:"*p1endl;

這是由于auto_ptr與unique_ptr的排他性所導(dǎo)致的!

為了解決這樣的問題,我們可以使用shared_ptr指針指針!

四、shared_ptr

熟悉了unique_ptr后,其實(shí)我們發(fā)現(xiàn)unique_ptr這種排他型的內(nèi)存管理并不能適應(yīng)所有情況,有很大的局限!如果需要多個(gè)指針變量共享怎么辦?

如果有一種方式,可以記錄引用特定內(nèi)存對象的智能指針數(shù)量,當(dāng)復(fù)制或拷貝時(shí),引用計(jì)數(shù)加1,當(dāng)智能指針析構(gòu)時(shí),引用計(jì)數(shù)減1,如果計(jì)數(shù)為零,代表已經(jīng)沒有指針指向這塊內(nèi)存,那么我們就釋放它!這就是shared_ptr采用的策略!

例:

classPerson{

public:

Person(intv){

this-no=v;

cout"構(gòu)造函數(shù)\tno="this-noendl;

~Person(){

cout"析構(gòu)函數(shù)\tno="this-noendl;

private:

intno;

//仿函數(shù),內(nèi)存刪除

classDestructPerson{

public:

voidoperator()(Person*pt){

cout"DestructPerson..."endl;

deletept;

};

引用計(jì)數(shù)的使用

調(diào)用use_count函數(shù)可以獲得當(dāng)前托管指針的引用計(jì)數(shù)。

shared_ptrPersonsp1;

shared_ptrPersonsp2(newPerson(2));

//獲取智能指針管控的共享指針的數(shù)量use_count():引用計(jì)數(shù)

cout"sp1use_count()="sp1.use_count()endl;

cout"sp2use_count()="sp2.use_count()endlendl;

//共享

sp1=sp2;

cout"sp1use_count()="sp1.use_count()endl;

cout"sp2use_count()="sp2.use_count()endlendl;

shared_ptrPersonsp3(sp1);

cout"sp1use_count()="sp1.use_count()endl;

cout"sp2use_count()="sp2.use_count()endl;

cout"sp2use_count()="sp3.use_count()endlendl;

如上代碼,sp1=sp2;和shared_ptrPersonsp3(sp1);就是在使用引用計(jì)數(shù)了。

sp1=sp2;--sp1和sp2共同托管同一個(gè)指針,所以他們的引用計(jì)數(shù)為2;

shared_ptrPersonsp3(sp1);--sp1和sp2和sp3共同托管同一個(gè)指針,所以他們的引用計(jì)數(shù)為3;

構(gòu)造

1).shared_ptrTsp1;空的shared_ptr,可以指向類型為T的對象

shared_ptrPersonsp1;

Person*person1=newPerson(1);

sp1.reset(person1);//托管person1

2).shared_ptrTsp2(newT());定義shared_ptr,同時(shí)指向類型為T的對象

shared_ptrPersonsp2(newPerson(2));

shared_ptrPersonsp3(sp1);

3).shared_ptrT[]sp4;空的shared_ptr,可以指向類型為T[]的數(shù)組對象C++17后支持

shared_ptrPerson[]sp4;

4).shared_ptrT[]sp5(newT[]{…});指向類型為T的數(shù)組對象C++17后支持

shared_ptrPerson[]sp5(newPerson[5]{3,4,5,6,7});

5).shared_ptrTsp6(NULL,D());//空的shared_ptr,接受一個(gè)D類型的刪除器,使用D釋放內(nèi)存

shared_ptrPersonsp6(NULL,DestructPerson());

6).shared_ptrTsp7(newT(),D());//定義shared_ptr,指向類型為T的對象,接受一個(gè)D類型的刪除器,使用D刪除器來釋放內(nèi)存

shared_ptrPersonsp7(newPerson(8),DestructPerson());

初始化

1).方式一:構(gòu)造函數(shù)

shared_ptrintup1(newint(10));//int(10)的引用計(jì)數(shù)為1

shared_ptrintup2(up1);//使用智能指針up1構(gòu)造up2,此時(shí)int(10)引用計(jì)數(shù)為2

2).方式二:使用make_shared初始化對象,分配內(nèi)存效率更高(推薦使用)

make_shared函數(shù)的主要功能是在動態(tài)內(nèi)存中分配一個(gè)對象并初始化它,返回指向此對象的shared_ptr;用法:

make_shared類型(構(gòu)造類型對象需要的參數(shù)列表);

shared_ptrintup3=make_sharedint//多個(gè)參數(shù)以逗號','隔開,最多接受十個(gè)

shared_ptrstringup4=make_sharedstring("字符串");

shared_ptrPersonup5=make_sharedPerson

賦值

shared_ptrrintup1(newint(10));//int(10)的引用計(jì)數(shù)為1

shared_ptrintup2(newint(11));//int(11)的引用計(jì)數(shù)為1

up1=up2;//int(10)的引用計(jì)數(shù)減1,計(jì)數(shù)歸零內(nèi)存釋放,up2共享int(11)給up1,int(11)的引用計(jì)數(shù)為2

主動釋放對象

shared_ptrrintup1(newint(10));

up1=nullptr;//int(10)的引用計(jì)數(shù)減1,計(jì)數(shù)歸零內(nèi)存釋放

up1=NULL;//作用同上

重置

p.reset();將p重置為空指針,所管理對象引用計(jì)數(shù)減1

p.reset(p1);將p重置為p1(的值),p管控的對象計(jì)數(shù)減1,p接管對p1指針的管控

p.reset(p1,d);將p重置為p1(的值),p管控的對象計(jì)數(shù)減1并使用d作為刪除器

p1是一個(gè)指針!

交換

p1和p2是智能指針

std::swap(p1,p2);//交換p1和p2管理的對象,原對象的引用計(jì)數(shù)不變

p1.swap(p2);//交換p1和p2管理的對象,原對象的引用計(jì)數(shù)不變

shared_ptr使用陷阱

shared_ptr作為被管控的對象的成員時(shí),小心因循環(huán)引用造成無法釋放資源!

如下代碼:

Boy類中有Girl的智能指針;

Girl類中有Boy的智能指針;

當(dāng)他們交叉互相持有對方的管理對象時(shí)…

#includeiostream

#includestring

#includememory

usingnamespacestd;

classGirl;

classBoy{

public:

Boy(){

cout"Boy構(gòu)造函數(shù)"endl;

~Boy(){

cout"~Boy析構(gòu)函數(shù)"endl;

voidsetGirlFriend(shared_ptrGirl_girlFriend){

this-girlFriend=_girlFriend;

private:

shared_p

溫馨提示

  • 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)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論