C++資源管理操作方法詳解
以對(duì)象管理資源
class A{...}; //工廠函數(shù)createA來(lái)提供特定的A對(duì)象 A* createA(); //壞情況 void f(){ A* p=createA(); ... delete p;//如何在delete之前程序先return了,則無(wú)法delete } //為了確保資源釋放 將資源放進(jìn)對(duì)象內(nèi) 利用對(duì)象的析構(gòu)函數(shù)來(lái)釋放 void f(){ std::shared_ptr<A> p(createA()); ... //程序結(jié)束后會(huì)經(jīng)shared_ptr的析構(gòu)函數(shù)釋放 }
auto_ptr已經(jīng)被廢除,主要原因是其拷貝會(huì)造成所以權(quán)轉(zhuǎn)移,所以使用shared_ptr更好
以對(duì)象管理資源的關(guān)鍵想法:
1、獲得資源后立刻放進(jìn)管理對(duì)象內(nèi)
2、管理對(duì)象運(yùn)用析構(gòu)函數(shù)釋放資源
注意是:shared_ptr和auto_ptr兩者都在析構(gòu)函數(shù)上使用delete而不是delete[],所以在動(dòng)態(tài)分配的數(shù)組上使用它們不好。當(dāng)然我覺(jué)得還是少用動(dòng)態(tài)數(shù)組,用vector,string啥的就能代替咯。
在資源管理類(lèi)中小心copy行為
復(fù)制RAII對(duì)象時(shí)有兩種選擇:
1、禁止復(fù)制--------將copying操作聲明為private
class Lock:private Uncopyable{ public: .... };
2、對(duì)底層資源祭出"引用計(jì)數(shù)法"--------即shared_ptr
class Lock{ public: explicit Lock(Mutex* pm):mutexPtr(pm,unlock)//unlock函數(shù)為刪除器 { lock(mutexPtr.get()); } private: shared_ptr<Mutex>mutexPtr; }
復(fù)制底部資源:需要資源管理類(lèi)對(duì)象的唯一理由是不需要某個(gè)復(fù)件資源時(shí)確保被釋放,在此情況下復(fù)制資源管理類(lèi)對(duì)象,應(yīng)該也復(fù)制其所包括的資源,即深拷貝------當(dāng)一個(gè)對(duì)象被復(fù)制時(shí),不論指針或其所指內(nèi)存都會(huì)被制作出一個(gè)復(fù)件,即深拷貝。
轉(zhuǎn)移底部資源所有權(quán):auto_ptr,你只希望有一個(gè)RAII對(duì)象指向一個(gè)未加工資源,即使被復(fù)制也是如此。
在資源管理類(lèi)中提供對(duì)原始資源的訪問(wèn)
前提:智能指針其實(shí)是一個(gè)類(lèi)
shared_ptr<A>p(createA()); //假如有以下函數(shù) int func(const A* pi); //如下調(diào)用錯(cuò)誤 因?yàn)閜是一個(gè)智能指針不是一個(gè)指向A的指針 int f=func(p); //調(diào)用get函數(shù)返回原始資源 int f=func(p.get());
智能指針重載了指針取值操作符(->,*) 允許隱式轉(zhuǎn)換到原始指針
//例如A有一個(gè)函數(shù),p是一個(gè)指向A的智能指針 int A::getNum(); //如下調(diào)用合格,其實(shí)是發(fā)生了一個(gè)智能指針到原始指針的隱式轉(zhuǎn)換 int num=p->getNum();
一般而言顯示轉(zhuǎn)換比較安全,隱式轉(zhuǎn)換客戶(hù)使用方便。
成對(duì)使用new和delete時(shí)要采用相同形式
delete的最大問(wèn)題在于:即將被刪除的內(nèi)存之內(nèi)究竟有多少個(gè)對(duì)象
即:被刪除的那個(gè)指針是指的單一對(duì)象還是成對(duì)數(shù)組?
string* p1=new string; string* p2=new string[100]; delete p1; delete[] p2;
規(guī)則很簡(jiǎn)單:new中用了[],delete就要用[]
以獨(dú)立語(yǔ)句將new對(duì)象置入智能指針
假設(shè)有一個(gè)函數(shù)來(lái)揭示處理程序的優(yōu)先權(quán),另一個(gè)函數(shù)用來(lái)在動(dòng)態(tài)分配所得的Widget上進(jìn)行某些帶有優(yōu)先權(quán)的處理
int priority(); void processWidget(shared_ptr<Widget>pw,int priority); //錯(cuò)誤 processWideget(new Widget,priority()); //因?yàn)閟hared_ptr的構(gòu)造函數(shù)需要一個(gè)原始指針,該構(gòu)造函數(shù)是explicit,無(wú)法隱式轉(zhuǎn)換 processWideget(shared_ptr<Widget>(new Widget),priority());//可以
但是編譯器執(zhí)行順序不確定,調(diào)用該函數(shù)前,編譯器需要:
調(diào)用priority,執(zhí)行new Widget,shared_ptr構(gòu)造函數(shù)
但調(diào)用priority的順序可以是第一第二或第三(new 和智能指針的先后順序不能變)
如何是先new,后priority,再shared_ptr,萬(wàn)一priority調(diào)用失常,則new出來(lái)的指針遺失,尚未置入shaerd_ptr的構(gòu)造函數(shù),則會(huì)資源泄漏。
因此分開(kāi)寫(xiě)最好:
shared_ptr<Widget>pw(new Wideget); processWidget(pw,priority());
到此這篇關(guān)于C++資源管理操作方法詳解的文章就介紹到這了,更多相關(guān)C++資源管理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言之循環(huán)語(yǔ)句詳細(xì)介紹
大家好,本篇文章主要講的是C語(yǔ)言之循環(huán)語(yǔ)句詳細(xì)介紹,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12C語(yǔ)言中 int main(int argc,char *argv[])的兩個(gè)參數(shù)詳解
這篇文章主要介紹了C語(yǔ)言中 int main(int argc,char *argv[])的兩個(gè)參數(shù)詳解的相關(guān)資料,需要的朋友可以參考下2017-03-03C語(yǔ)言實(shí)現(xiàn)無(wú)規(guī)律數(shù)據(jù)加密、解密功能
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)無(wú)規(guī)律數(shù)據(jù)加密、解密功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-03-03如何運(yùn)用Capstone實(shí)現(xiàn)64位進(jìn)程鉤子掃描
本章將通過(guò)Capstone引擎實(shí)現(xiàn)64位進(jìn)程鉤子的掃描,讀者可使用此段代碼檢測(cè)目標(biāo)進(jìn)程內(nèi)是否被掛了鉤子,感興趣的朋友跟隨小編一起看看吧2024-08-08關(guān)于背包問(wèn)題的一些理解和應(yīng)用
這篇文章主要介紹了關(guān)于背包問(wèn)題的一些理解和應(yīng)用,本文可以說(shuō)是背包問(wèn)題九講的補(bǔ)充、讀后感,需要的朋友可以參考下2014-08-08全面了解結(jié)構(gòu)體、聯(lián)合體和枚舉類(lèi)型
下面小編就為大家?guī)?lái)一篇全面了解結(jié)構(gòu)體、聯(lián)合體和枚舉類(lèi)型。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-07-07