




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第C++智能指針詳解目錄一.unique_ptr獨(dú)占指針特點(diǎn)創(chuàng)建方式傳遞方式簡單使用隱藏危險(xiǎn)二.shared_ptr計(jì)數(shù)指針特點(diǎn)傳遞方式隱藏危險(xiǎn)三.weak_ptr優(yōu)缺點(diǎn):
智能指針由原始指針的封裝,優(yōu)點(diǎn)是可以自動分配內(nèi)存,不用擔(dān)心內(nèi)存泄漏問題。用于解決獨(dú)占/共享所有權(quán)指針的釋放,傳輸?shù)葐栴}。但是沒有原始指針方便。
一.unique_ptr獨(dú)占指針
特點(diǎn)
都是圍繞獨(dú)占展開
特點(diǎn)一:如其名,獨(dú)占。也就是說同一個(gè)內(nèi)存空間同時(shí)只能有一個(gè)指針來管理。
int*pi=newint(10);//利用傳統(tǒng)指針在堆區(qū)開辟一個(gè)存放整數(shù)的區(qū)域
std::unique_ptrintu_pi_01{pi};//通過傳統(tǒng)指針創(chuàng)建智能指針
std::unique_ptrintu_pi_02{pi};//有意讓兩個(gè)獨(dú)占指針同時(shí)指向同一個(gè)內(nèi)存區(qū)域
這么寫編譯器不會報(bào)錯(cuò),但運(yùn)行時(shí)會提示error:doublefreedetectedintcache2
這也就印證了第一個(gè)特點(diǎn),一個(gè)內(nèi)存區(qū)域只能由一個(gè)指針管理。
特點(diǎn)二:當(dāng)指針超出作用域時(shí),內(nèi)存自動釋放
//由于指針的本質(zhì)也是變量,離開作用范圍就會自動釋放
//因此我們需要通過在外部創(chuàng)建變量來保存指針?biāo)4娴牡刂?/p>
int*external_pi_1;//用于存儲傳統(tǒng)指針的地址
int*external_pi_2;//用于存儲智能指針的地址
int*pi=newint(10);//使用傳統(tǒng)指針在堆區(qū)開辟內(nèi)存存儲整形
external_pi_1=pi;
std::unique_ptrintu_pi{newint(10)};//使用智能指針在堆區(qū)開辟內(nèi)存存儲
external_pi_2=u_pi.get();
std::cout*external_pi_1std::endl;//輸出10
std::cout*external_pi_2std::endl;//輸出10
std::cout*external_pi_1std::endl;//輸出10
std::cout*external_pi_2std::endl;//輸出0
可見傳統(tǒng)指針在局部作用域中開辟的內(nèi)存在外部同樣可以訪問,也就是說我們使用傳統(tǒng)指針開辟內(nèi)存之后在離開作用域時(shí)需要加上釋放內(nèi)存的操作,不然會造成內(nèi)存泄漏。
而智能指針我們不需要手動釋放內(nèi)存,在離開作用域后會自動釋放。
特點(diǎn)三:由于特點(diǎn)一,修改指針不可以copy,只能Move(轉(zhuǎn)移歸屬權(quán))
std::unique_ptrintu_pi1=std::make_uniqueint(10);
//std::unique_ptrintu_pi2=u_pi1;//嘗試用拷貝的方式共享內(nèi)存,error:可別忘了這是獨(dú)占指針
std::unique_ptrintu_pi2=move(u_pi1);使用move方法轉(zhuǎn)移內(nèi)存擁有權(quán)。
也就是說,通過move函數(shù),把指針u_pi1所指內(nèi)存中的值掏空,然后安到指針u_pi2所指的內(nèi)存上。
創(chuàng)建方式
方式一:通過已有的傳統(tǒng)指針創(chuàng)建
int*pi=newint(10);//使用傳統(tǒng)指針在堆區(qū)開辟一個(gè)空間
std::unique_ptrintu_pi{pi};//利用創(chuàng)通指針創(chuàng)建智能指針
方式二:通過new方法創(chuàng)建
std::unique_ptrintu_pi{newint(10)};
方式三:通過std::make_unique創(chuàng)建
std::unipue_ptrintu_pi=std::make_uniqueint(10);
傳遞方式
方式一:通過move(),轉(zhuǎn)移擁有權(quán).
voidshow(std::unique_ptrintu_pi)
std::cout*u_pistd::endl;
voidtest()
std::unique_ptrintu_pi{newint(10)};
show(move(u_pi));//通過move轉(zhuǎn)移擁有權(quán)
}
注意:將指針的擁有權(quán)轉(zhuǎn)入函數(shù)中后,在原作用域指針將被釋放,而該指針將在函數(shù)調(diào)用結(jié)束時(shí)釋放。也就是說,將智能指針以move的形式傳入函數(shù)后,在原作用域不能再使用該指針。
方式二:通過引用傳遞
voidshow(conststd::unique_ptrintu_pi)//加cosnt不是不能改變指向的值,不能改變指針的指向
std::cout*u_pistd::endl;
//u_pi.reset();加了const所以不能清空
voidtest()
std::unique_ptrintu_pi{newint(10)};
show(u_pi);
}
注意:將指針以引用的方式傳入函數(shù),那么該指針在原作用域依然存活,并可以和所調(diào)用函數(shù)共同操作該內(nèi)存空間數(shù)據(jù)。
方式三:鏈?zhǔn)絺鬟f
std::unique_ptrPersonget_unique(std::stringstr)
std::unique_ptrPersonu_pi{newPerson(str)};
returnu_pi;
voidtest()
get_unique("hua")-show();//鏈?zhǔn)?/p>
}
簡單使用
通過get()獲取地址可以通過-調(diào)用成員函數(shù)可以通過*調(diào)用解引用通過reset()清空指針
classPerson
public:
Perosn(std::stringname):m_name(name){};
voidshow()
std::cout"nameis"m_namestd::endl;
private:
std::stringm_name;
intmain()
std::unique_ptrPersonu_p{newPerson("kimi")};//用自定義類型創(chuàng)建
u_p-show();//可以通過-調(diào)用函數(shù)
(*u_p).show();//通過*解引用
std::coutu_p.get()std::endl;//通過get()獲取地址
u_p.reset();//清空指針
return0;
}
隱藏危險(xiǎn)
用已有指針創(chuàng)建時(shí),沒有及時(shí)清空傳統(tǒng)指針,導(dǎo)致同時(shí)有兩個(gè)指針指向這塊已經(jīng)被獨(dú)占的區(qū)域。
int*pi=newint(10);
std::unique_ptrintu_pi{pi};//使用傳統(tǒng)指針創(chuàng)建,上式開辟的區(qū)域被獨(dú)占
*pi=20;//沒有及時(shí)清空,依然可以通過獨(dú)占指針以外的方式修改內(nèi)存
二.shared_ptr計(jì)數(shù)指針
特點(diǎn)一:可以通過copy共享內(nèi)存。
std::shared_ptrintu_pi_1{newint(10)};
std::shared_ptrintu_pi_2=u_pi_1;//通過復(fù)制拷貝
特點(diǎn)二:通過use_count();來查看計(jì)數(shù),copy計(jì)數(shù)加一,銷毀計(jì)數(shù)減一。
std::shanred_ptrints_pi{newint(10)};//s_pi.use_count()==1
std::shanred_ptrints_pi_copy=s_pi;//s_pi.use_count()==2
s_pi=nullptr;//清空指針//s_pi_copy.use_count()==1
特點(diǎn)三:無論多少指針,都同用一份數(shù)據(jù),因而同一份數(shù)據(jù)的use_count()一致。
std::shared_ptrints_pi{newint(10)};//s_pi.use_count()==1
std::shared_ptrints_pi_2=s_pi;//s_pi.use_count()==2
std::shared_ptrints_pi_3=s_pi_2;//s_pi.use_count()==3
s_pi_2=bullptr;//清空2指針//s_pi.use_count()==2
本質(zhì)不變,在函數(shù)調(diào)用中,因?yàn)楸旧碇С謴?fù)制操作,所以不用加move可以直接傳遞。并且在傳遞到函數(shù)中,use_count()會增加,并在函數(shù)銷毀時(shí)候還原。在函數(shù)中修改指向的值,在外部的指針指向的值也會改變。使用引用傳遞,則在傳遞到函數(shù)中時(shí),計(jì)數(shù)不會增加。
voidget_use_1(std::shared_ptrints_pi)
std::couts_pi.use_count()std::endl;
voidget_use_2(std::shared_ptrints_pi)
std::couts_pi.use_count()std::endl;
voidtest()
std::shared_ptrints_pi{newint(10)};
std::couts_pi.use_count()std::endl;
get_use_1(s_pi);//在函數(shù)中計(jì)數(shù)會增加,但隨著函數(shù)銷毀,計(jì)數(shù)復(fù)原
get_use_2(s_pi);//以引用方式傳入,指針還是那個(gè)指針,計(jì)數(shù)不會增加
}
輸出:121
share_ptr帶來的循環(huán)依賴問題
classPerson
public:
voidset_friend(share_ptrPersonp)
_friend=p;
private:
share_ptrPerson_frient;
intmain()
share_ptrPersonp1=make_shared("P1");
share_ptrPersonp2=make_shared("P2");
p1-set_friend(P2);
p2-set_friend(P1);//造成循環(huán)依賴,在main中的話,不會執(zhí)行析構(gòu)
}
解決:將_friend屬性改為weak_ptr。
三.weak_ptr
weak_ptr是一個(gè)不需要所有權(quán)的指針,所以我們可以通過用weak_ptr來聲明屬性,解決循環(huán)依賴
classPerson
public:
voidset_friend(share_ptrPersonp)
_friend=p;
private:
weak_ptrPerson_frient;//使用weak_ptr解決循環(huán)依賴
intmain()
share_ptrPersonp1
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- pcep考試題庫及答案
- CRA基礎(chǔ)知識培訓(xùn)課件
- 多變的繩結(jié)教學(xué)課件
- 2025年嘉興出租車公共科目考試題
- 市政道路安全匯報(bào)
- 外科快速康復(fù)護(hù)理開展
- 大學(xué)空間幾何講解
- 皮膚感染病人的健康教育
- 2025年免疫球蛋白診斷血清項(xiàng)目建議書
- 工程部技術(shù)員工作總結(jié)
- 2025藥劑學(xué)試題和答案
- 重慶發(fā)展能源有限公司招聘考試真題2024
- 2024年度蘇州寫字樓市場報(bào)告-施沃特SWT
- 二零二五年度婚介服務(wù)合同標(biāo)準(zhǔn)范本及附件
- 安全生產(chǎn)車間員工培訓(xùn)內(nèi)容
- 2025年考研政治試題及其答案解析
- 提升高價(jià)值專利培育培訓(xùn)
- 醫(yī)院健康教育內(nèi)容及方式
- 浙江臺州市2024-2025學(xué)年高二下學(xué)期6月期末數(shù)學(xué)(含答案)
- 業(yè)務(wù)人員財(cái)務(wù)培訓(xùn)
- 4m1e基礎(chǔ)知識培訓(xùn)
評論
0/150
提交評論