|
在C++中,我們常用指針去使用某個(gè)對(duì)象實(shí)例,但隨著代碼對(duì)該對(duì)象使用的增加,比如越來(lái)越多的其它的類或模塊需要使用該對(duì)象,那么什么時(shí)候安全地釋放該對(duì)象就是個(gè)問(wèn)題。比如,某處使用完該對(duì)象后,認(rèn)為不再使用,便釋放了它,但另外的某些類或模塊還需使用,這時(shí),就會(huì)引起內(nèi)存的非法使用問(wèn)題,在Linux下是signal 11錯(cuò)誤,也就是段錯(cuò)誤(Segmentation Fault)。為了解決這種問(wèn)題,引入了智能指針,當(dāng)使用該對(duì)象時(shí),令其引用計(jì)數(shù)加1,釋放時(shí)只是減去1。當(dāng)減為0時(shí),就自動(dòng)釋放指針?biāo)笇?duì)象。C++中,通常使用模板實(shí)現(xiàn)這一機(jī)制。但是當(dāng)兩個(gè)智能指針相互引用對(duì)方時(shí),即使其它地方都釋放它們,它們的引用計(jì)數(shù)也會(huì)為1,最終導(dǎo)致內(nèi)存泄漏。這就引入了弱指針的概念。 Android中的隨處可見(jiàn)的sp<XXX>和wp<XXX>。這里的XXX是對(duì)象的類,sp和wp是模版,分別實(shí)現(xiàn)了強(qiáng)指針(Strong Pointer)和弱指針(Weak Pointer)。模板具體化后的一個(gè)實(shí)例XXX,具有指針的屬性,可以簡(jiǎn)單地把它理解一個(gè)指針,只不過(guò)比普通的指針特殊一點(diǎn)而已。弱指針不能直接被當(dāng)作指針來(lái)使用,當(dāng)需要當(dāng)作指針來(lái)使用時(shí),需要使用其成員函數(shù)promote來(lái)“提升”為強(qiáng)指針。弱指針指向的對(duì)象可能已經(jīng)被銷毀,這時(shí),若使用promote得到的指針為空指針。
引用計(jì)數(shù)功能的實(shí)現(xiàn) RefBase是引用計(jì)數(shù)的基類(見(jiàn)文件RefBase.h),在它里面還定義了一個(gè)嵌套類weakref_type,在其實(shí)現(xiàn)文件RefBase.cpp里還定義了一個(gè)類weakref_impl ,它繼承自嵌套類weakref_type,而RefBase中包含一個(gè)私有數(shù)據(jù)成員:指向weakref_impl 的指針。可以看出,RefBase中的數(shù)據(jù)實(shí)體就是weakref_impl,后者繼承自其嵌套類weakref_type。其示意圖如下:
這樣,相當(dāng)于將一部分成員函數(shù)(weakref_type的成員函數(shù))和數(shù)據(jù)成員(weakref_impl的數(shù)據(jù)成員)封裝起來(lái),作為私有的一個(gè)邏輯實(shí)體,只被Refbase內(nèi)部的實(shí)現(xiàn)使用,而RefBase的公有成員才是外界使用的API。RefBase通過(guò)指針mRefs使用內(nèi)部的引用計(jì)數(shù)數(shù)據(jù)。而內(nèi)部引用計(jì)數(shù)實(shí)體對(duì)象也可以通過(guò) mBase這個(gè)成員來(lái)使用其“容器”對(duì)象RefBase. weakref_impl里面的數(shù)據(jù)成員信息如下: volatile int32_t mStrong;//強(qiáng)引用計(jì)數(shù)
強(qiáng)指針和弱指針都是模板類: template <typename T> class sp{ //……此處省略了部分代碼 inline T& operator* () const { return *m_ptr; } //……此處省略了部分代碼 T* m_ptr;//實(shí)際指向?qū)ο蟮闹羔?/span> }; template <typename T> class wp{ //……此處省略了部分代碼 sp<T>promote() const; //……此處省略了部分代碼 T* m_ptr; }; 強(qiáng)指針因?yàn)橹剌d了兩個(gè)操作符*和->,因此具有形式上跟普通指針一樣的用法,而弱指則沒(méi)有重載這兩個(gè)操作符,只能先被“提升”為強(qiáng)指針后,才可以當(dāng)作普通指針來(lái)使用。 如果需要使用智能指針將對(duì)象保護(hù)起來(lái),只要讓其繼承RefBase,并將析構(gòu)函數(shù)聲明為virtual的,就可以使用智能指針。
可以參考鏈接來(lái)獲取詳細(xì)介紹:
參考: Android系統(tǒng)的智能指針(輕量級(jí)指針、強(qiáng)指針和弱指針)的實(shí)現(xiàn)原理分析 |
|
|