智能指針的三種常見寫法:
創(chuàng)新互聯(lián)公司是一家專業(yè)提供科爾沁左翼企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、H5技術(shù)、小程序制作等業(yè)務(wù)。10年已為科爾沁左翼眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站制作公司優(yōu)惠進(jìn)行中。
一、最開始的原始寫法,原始寫法可以理解為指針轉(zhuǎn)移的方法。
templateclass AutoPtr { public: AutoPtr() :_ptr(NULL) {} AutoPtr(T* ptr) :_ptr(ptr) {} ~AutoPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } AutoPtr (AutoPtr & ap) : _ptr(ap._ptr) { ap._ptr = NULL; } AutoPtr & operator = (AutoPtr & ap) { if (this != &ap) { delete _ptr; _ptr = ap._ptr; ap._ptr = NULL; } return *this; } T& operator*() { return *_ptr; } T* GerPtr() { return _ptr; } private: T* _ptr; };
二、演變?yōu)楹髞淼膕coped寫法,又可以稱作守衛(wèi)寫法。該寫法相對(duì)于原始寫法的優(yōu)點(diǎn)在于不讓使用拷貝構(gòu)造和運(yùn)算符的重載,這樣就避免了深淺拷貝的指針問題。做法是把拷貝構(gòu)造、運(yùn)算符的重載定聲明出來而不定義,并且用protected保護(hù)起來。scoped寫法是引用的boost庫(kù)。有興趣的可以去了解一下這個(gè)東西,背后還是有很多故事的,在這我就不多說啦。
templateclass scopedPtr { public: scopedPtr() :_ptr(NULL) {} scopedPtr(T* ptr) :_ptr(ptr) {} ~scopedPtr() { if (_ptr) { delete _ptr; _ptr = NULL; } } T& operator*() { return *_ptr; } T* operator->() { return _ptr; } T* GetPtr() { return _ptr; } protected: //加上protected可以防止使用者在類之外定義拷貝構(gòu)造和運(yùn)算符的重載函數(shù) scopedPtr (const scopedPtr & sp); //不讓使用者使用拷貝,可以防止拷貝,所以只聲明不定義 scopedPtr & operator=(const scopedPtr & sp); private: T* _ptr; };
三、sharedPtr寫法
這種方法考慮了深淺拷貝問題并且引用了引用計(jì)數(shù)器來解決淺拷貝的問題,比較完善的實(shí)現(xiàn)了智能指針想要實(shí)現(xiàn)的功能。
templateclass SharePtr { public: SharePtr(T* ptr) :_ptr(ptr) , _pCount(new int(1)) {} //SharePtr(Shar) // :_ptr(sp._ptr) //{ // *_pCount = 1; //} ~SharePtr() { if (_ptr) { if (--(*_pCount) == 0) { delete _ptr; delete _pCount; _ptr = NULL; _pCount = NULL; } _ptr = NULL; } } SharePtr (const SharePtr & sp) { _ptr = sp._ptr; _pCount = sp._pCount; ++(*_pCount); } SharePtr & operator=(const SharePtr & sp) { if (this != &sp) { if (--(*_pCount) == 0) //這里要分清楚是誰減一,邏輯需要分析清楚 { delete _ptr; delete _pCount; _ptr = NULL; _pCount = NULL; } _ptr = sp._ptr; _pCount = sp._pCount; ++(*_pCount); } return *this; } private: T* _ptr; int* _pCount; };