在C語(yǔ)言中我們用指針來(lái)進(jìn)行內(nèi)存管理,這也是C語(yǔ)言的強(qiáng)大之處。然而,也正是指針的存在使得C語(yǔ)言變得令人懊惱,內(nèi)存泄漏、垂懸指針等等問(wèn)題。強(qiáng)大的C++則采用智能指針(Smart_Ptr)來(lái)處理這個(gè)問(wèn)題.
好了,什么是智能指針呢?智能指針的行為類(lèi)似常規(guī)指針,重要的區(qū)別是它負(fù)責(zé)自動(dòng)釋放所指向的對(duì)象。這樣以防止內(nèi)存泄漏。
智能指針都有哪些種類(lèi)呢?
通過(guò)上述表格可以看出有如此多的智能指針,C11標(biāo)準(zhǔn)庫(kù)已經(jīng)引進(jìn)unique_ptr/shared_ptr/weak_ptr供我們使用。
下面來(lái)簡(jiǎn)單談?wù)勥@些指針的原理和實(shí)現(xiàn)。
First——>auto ptr
auto ptr的實(shí)現(xiàn)原理主要是管理權(quán)的轉(zhuǎn)移。它是所擁有的對(duì)象的唯一擁有者,也就是一個(gè)對(duì)象只有一個(gè)擁有者。
代碼實(shí)現(xiàn):
template <class T> class AutoPtr { public: AutoPtr(T* Ptr) :_Ptr(Ptr) {} ~AutoPtr() { if(_Ptr!=NULL) { delete _Ptr; } } AutoPtr(AutoPtr<T>& ap) { _Ptr=ap._Ptr; ap._Ptr=NULL; } AutoPtr<T> operator=(AutoPtr<T>& ap) { if(&ap!=this) { delete _Ptr; _Ptr=ap._Ptr; ap._Ptr=NULL; } return *this; } T& operator*() { return *_Ptr; } T* operator->() { return _Ptr; } private: T* _Ptr; };
通過(guò)代碼我們可以看出由于auto ptr指針唯一性,即一個(gè)對(duì)象只能有一個(gè)auto ptr指針?biāo)赶蛩?。因此,?dāng)auto ptr以傳值方式被作為參數(shù)傳遞給某函數(shù)時(shí),這時(shí)對(duì)象的原來(lái)?yè)碛姓呔头艞壛藢?duì)象的擁有權(quán),把它轉(zhuǎn)移到被調(diào)用函數(shù)中的參數(shù)上,如果函數(shù)不再將擁有權(quán)傳遞出去,由于形參的作用域僅僅為函數(shù)內(nèi)部,當(dāng)函數(shù)退出時(shí),它所指向的對(duì)象將被銷(xiāo)毀。當(dāng)函數(shù)返回一個(gè)auto ptr時(shí),其擁有權(quán)又被轉(zhuǎn)移到了調(diào)用端。因此,我們盡量不要使用auto ptr傳參,或者引用傳遞。此外,auto ptr 還不能作為容器的成員,C++標(biāo)準(zhǔn)明確禁止這樣做。
Second——>scoped ptr
scoped ptr與auto ptr類(lèi)似,它實(shí)現(xiàn)的原理則是防拷貝,也就是它不能轉(zhuǎn)移管理權(quán),所以不能被賦值或者拷貝構(gòu)造。那么,我們可以將拷貝構(gòu)造和賦值運(yùn)算符重載函數(shù)只聲明不實(shí)現(xiàn),并將其聲明為保護(hù),那么也就防止了別人在類(lèi)外實(shí)現(xiàn)它。
代碼實(shí)現(xiàn):
template <class T> class ScopedPtr { public: ScopedPtr(T* Ptr) :_Ptr(Ptr) {} ~ScopedPtr() { if(_Ptr!=NULL) { delete _Ptr; } } T& operator*() { return *_Ptr; } T* operator->() { return _Ptr; } protected: T* _Ptr; ScopedPtr(ScopedPtr<T>& sp); ScopedPtr<T>& operator=(ScopedPtr<T>& sp); };
通過(guò)代碼可以看出scoped ptr 的實(shí)現(xiàn)十分的簡(jiǎn)單粗暴,動(dòng)態(tài)分配對(duì)象的生命周期限制在特定的作用域,采用scoped ptr可以有作用域保護(hù),使用起來(lái)也優(yōu)于auto ptr。
Third——>shared ptr
shared ptr顧名思義就是共享,所以也就是說(shuō)多個(gè)指針可以指向同一個(gè)內(nèi)存,它所采用的是引用計(jì)數(shù)的原理,也就是引進(jìn)了一個(gè)計(jì)數(shù)器shared_count,用來(lái)表示當(dāng)前有多少個(gè)智能指針對(duì)象共享指針指向的內(nèi)存。因此shared_ptr可以做為STL容器的元素。析構(gòu)函數(shù)中不是直接釋放指針對(duì)應(yīng)的內(nèi)塊,shared_count大于1則不釋放內(nèi)存只是將引用計(jì)數(shù)減1,只是計(jì)數(shù)等于1時(shí)釋放內(nèi)存。這樣避免了一塊內(nèi)存被多次析構(gòu)的問(wèn)題。
代碼實(shí)現(xiàn):
template <class T> class SharedPtr { public: SharedPtr(T* Ptr) :_Ptr(Ptr) ,_Pcount(new long(1)) {} ~SharedPtr() { _Release(); } SharedPtr(SharedPtr<T>& sp) :_Ptr(sp._Ptr) ,_Pcount(sp._Pcount) { ++(*_Pcount); } SharedPtr<T>& operator=(SharedPtr<T>& sp) { if(&sp!=this) { _Release(); _Ptr=sp._Ptr; _Pcount=sp._Pcount; ++(*_Pcount); } } T& operator*() { return *_Ptr; } T* operator->() { return _Ptr; } long UseCount() { return *_Pcount; } T* GetPtr() { return _Ptr; } protected: T* _Ptr; long *_Pcount; void _Release() { if(--(*_Pcount)==0) { delete _Ptr; delete _Pcount; } } };
由上述代碼可知,我們?cè)诳截惡唾x值也會(huì)將引用計(jì)數(shù)進(jìn)行遞增,而實(shí)現(xiàn)也只是一般的復(fù)制。
動(dòng)態(tài)對(duì)象的正確釋放是編程中最容易出錯(cuò)的地方,利用智能指針可以更安全的使用動(dòng)態(tài)對(duì)象,使得我們的程序更高效、安全。
創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。
標(biāo)題名稱(chēng):智能指針的簡(jiǎn)單剖析和實(shí)現(xiàn)-創(chuàng)新互聯(lián)
URL鏈接:http://www.rwnh.cn/article24/hcoje.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化、電子商務(wù)、外貿(mào)建站、企業(yè)建站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容