理解關(guān)于Android系統(tǒng)中輕量級(jí)指針的實(shí)現(xiàn)
智能指針來(lái)源
引發(fā)指針錯(cuò)誤情況表現(xiàn)常常有如下幾個(gè)表現(xiàn)情況:
1.申請(qǐng)了內(nèi)存空間,但是忘記釋放指針?biāo)赶虻膶?duì)象占用的內(nèi)存空間。
2.使用了無(wú)效的指針。
因此在android的C++代碼部分采用了智能指針的技術(shù)。智能指針通過(guò)一種能夠自動(dòng)危害對(duì)象引用計(jì)數(shù)的技術(shù)。來(lái)解決C++中指針存在的缺陷問(wèn)題。
在android系統(tǒng)中提供了三種類(lèi)型的C++智能指針,分別為:輕量級(jí)智能指針、強(qiáng)指針、弱指針。
下面主要通過(guò)進(jìn)行分析輕量級(jí)指針的實(shí)現(xiàn)原理。
輕量級(jí)指針
輕量級(jí)指針就是通過(guò)利用簡(jiǎn)單的引用計(jì)數(shù)計(jì)數(shù)類(lèi)維護(hù)對(duì)象的生命周期,如果一個(gè)類(lèi)的對(duì)象支持使用輕量級(jí)指針,那么它就必須要從LightRefBase類(lèi)進(jìn)行繼承,因?yàn)檫@個(gè)LightRefBase類(lèi)提供了一個(gè)簡(jiǎn)單的引用計(jì)數(shù)器。
LightRefBase類(lèi)定義
下面的源碼主要依據(jù)android5.0的源碼進(jìn)行分析的。LightRefBase類(lèi)的定義在android系統(tǒng)中的\frameworks\rs\cpp\util\RefBase.h 這個(gè)文件中。
LightRefBase類(lèi)也是一個(gè)模板類(lèi)。模板參數(shù)T表示對(duì)象的實(shí)際類(lèi)型,它必須進(jìn)行對(duì)LightRefBase這個(gè)類(lèi)繼承。
//模板類(lèi)
template <class T>
class LightRefBase
{
public:
//公共的內(nèi)聯(lián)函數(shù)
inline LightRefBase() : mCount(0) { }
inline void incStrong(__attribute__((unused)) const void* id) const {
__sync_fetch_and_add(&mCount, 1);
}
inline void decStrong(__attribute__((unused)) const void* id) const {
if (__sync_fetch_and_sub(&mCount, 1) == 1) {
delete static_cast<const T*>(this);
}
}
//! DEBUGGING ONLY: Get current strong ref count.
inline int32_t getStrongCount() const {
return mCount;
}
typedef LightRefBase<T> basetype;
protected:
//內(nèi)聯(lián)的虛構(gòu)函數(shù)
inline ~LightRefBase() { }
private:
friend class ReferenceMover;
inline static void moveReferences(void*, void const*, size_t,
const ReferenceConverterBase&) { }
private:
mutable volatile int32_t mCount;
};
上面LightRefBase類(lèi)定義涉及到幾個(gè)知識(shí)點(diǎn):
- 1、C++的三個(gè)訪問(wèn)權(quán)限類(lèi)型:public、protected、private。
public:可以被任意實(shí)體訪問(wèn)。
protected:只允許子類(lèi)及本類(lèi)的成員函數(shù)訪問(wèn)。
private:只允許本類(lèi)的成員函數(shù)訪問(wèn)。
- 2、C++中的inline內(nèi)聯(lián)函數(shù)
在函數(shù)第一部分如果包含有inline關(guān)鍵字的函數(shù),那么這個(gè)函數(shù)就表示為內(nèi)聯(lián)函數(shù)。內(nèi)聯(lián)函數(shù)主要為了解決一些頻繁調(diào)用的小函數(shù)大量消耗??臻g(棧內(nèi)存)的問(wèn)題。
inline的使用是有所限制的,inline只適合涵數(shù)體內(nèi)代碼簡(jiǎn)單的涵數(shù)使用,不能包含復(fù)雜的結(jié)構(gòu)控制語(yǔ)句例如while、switch,并且不能內(nèi)聯(lián)函數(shù)本身不能是直接遞歸函數(shù)(遞歸函數(shù):自己內(nèi)部還調(diào)用自己的函數(shù))。
- 3、C++中的friend友元函數(shù)
C++中的友元機(jī)制允許類(lèi)的非公有成員被一個(gè)類(lèi)或者函數(shù)訪問(wèn),友元按類(lèi)型分為三種:普通非類(lèi)成員函數(shù)作為友元,類(lèi)的成員函數(shù)作為友元,類(lèi)作為友元。
友元函數(shù)是可以直接訪問(wèn)類(lèi)的私有成員的非成員函數(shù)。它是定義在類(lèi)外的普通函數(shù),它不屬于任何類(lèi),但需要在類(lèi)的定義中加以聲明,聲明時(shí)只需在友元的名稱(chēng)前加上關(guān)鍵字friend。
- 4、C++中的mutable關(guān)鍵字
mutable是為了突破const的限制而設(shè)置的。被mutable修飾的變量,將永遠(yuǎn)處于可變的狀態(tài),即使在一個(gè)const函數(shù)中。
- 5、C++中的template類(lèi)模板
一個(gè)類(lèi)模板(也稱(chēng)為類(lèi)屬類(lèi)或類(lèi)生成類(lèi))同意用戶(hù)為類(lèi)定義一種模式。使得類(lèi)中的某些數(shù)據(jù)成員、默寫(xiě)成員函數(shù)的參數(shù)、某些成員函數(shù)的返回值,能夠取隨意類(lèi)型(包含系統(tǒng)提前定義的和用戶(hù)自己定義的)。
類(lèi)模板的應(yīng)用場(chǎng)景:多個(gè)類(lèi)有著共同操作,但是數(shù)據(jù)類(lèi)型不同。
LightRefBase的實(shí)現(xiàn)類(lèi)
輕量級(jí)LightRefBase類(lèi)的實(shí)現(xiàn)類(lèi)為wp類(lèi),它也是在\frameworks\rs\cpp\util\RefBase.h 這個(gè)文件中。wp也是一個(gè)模板類(lèi),模板參數(shù)T表示的是對(duì)象的實(shí)際類(lèi)型,它必須繼承LightRefBase類(lèi)。由于wp類(lèi)也是強(qiáng)指針的實(shí)現(xiàn)類(lèi),因此我們只需要分析下該wp類(lèi)中關(guān)于輕量級(jí)指針類(lèi)的實(shí)現(xiàn)部分就可以了。
//模板類(lèi)
template <typename T>
class wp
{
public:
typedef typename RefBase::weakref_type weakref_type;
//輕量級(jí)指針需要用到的構(gòu)造函數(shù)
inline wp() : m_ptr(0) { }
wp(T* other);
wp(const wp<T>& other);
wp(const sp<T>& other);
template<typename U> wp(U* other);
template<typename U> wp(const sp<U>& other);
template<typename U> wp(const wp<U>& other);
//輕量級(jí)指針需要用到的虛構(gòu)函數(shù)
~wp();
// Assignment
wp& operator = (T* other);
wp& operator = (const wp<T>& other);
wp& operator = (const sp<T>& other);
template<typename U> wp& operator = (U* other);
template<typename U> wp& operator = (const wp<U>& other);
template<typename U> wp& operator = (const sp<U>& other);
void set_object_and_refs(T* other, weakref_type* refs);
// promotion to sp
sp<T> promote() const;
// Reset
void clear();
// Accessors
inline weakref_type* get_refs() const { return m_refs; }
inline T* unsafe_get() const { return m_ptr; }
// Operators
COMPARE_WEAK(==)
COMPARE_WEAK(!=)
COMPARE_WEAK(>)
COMPARE_WEAK(<)
COMPARE_WEAK(<=)
COMPARE_WEAK(>=)
inline bool operator == (const wp<T>& o) const {
return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
}
template<typename U>
inline bool operator == (const wp<U>& o) const {
return m_ptr == o.m_ptr;
}
inline bool operator > (const wp<T>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
template<typename U>
inline bool operator > (const wp<U>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
}
inline bool operator < (const wp<T>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
template<typename U>
inline bool operator < (const wp<U>& o) const {
return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
}
inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
private:
template<typename Y> friend class sp;
template<typename Y> friend class wp;
//輕量級(jí)指針會(huì)用到的變量m_ptr
T* m_ptr;
weakref_type* m_refs;
};
總結(jié)
通過(guò)前面的概念和系統(tǒng)源碼實(shí)現(xiàn)功能原理分析,我們?nèi)绻褂幂p量級(jí)指針的話(huà),那么要包含頭文件并采用繼承LightRefBase類(lèi)的方式,那么就可以使用輕量級(jí)指針的功能了。
到此這篇關(guān)于理解關(guān)于Android系統(tǒng)中輕量級(jí)指針的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Android 輕量級(jí)指針 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android入門(mén)之使用SharedPreference存取信息詳解
這篇文章主要為大家詳細(xì)介紹了Android如何使用SharedPreference實(shí)現(xiàn)存取信息,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Android有一定的幫助,需要的可以參考一下2022-12-12
Android使用ExpandableListView實(shí)現(xiàn)三層嵌套折疊菜單
這篇文章主要介紹了Android使用ExpandableListView實(shí)現(xiàn)三層嵌套折疊菜單,對(duì)布局感興趣的同學(xué)可以參考下2021-04-04
Android設(shè)計(jì)模式之Builder模式解析
這篇文章主要為大家詳細(xì)介紹了Android設(shè)計(jì)模式之Builder模式解析的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10
Android實(shí)現(xiàn)EventBus登錄界面與傳值(粘性事件)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)EventBus登錄界面與傳值,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11
系統(tǒng)應(yīng)用根據(jù)Uri授予權(quán)限方法詳解
這篇文章主要為大家介紹了系統(tǒng)應(yīng)用根據(jù)Uri授予權(quán)限方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Android自定義控件通用驗(yàn)證碼輸入框的實(shí)現(xiàn)
這篇文章主要介紹了Android自定義控件通用驗(yàn)證碼輸入框的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
Android中創(chuàng)建快捷方式代碼實(shí)例
這篇文章主要介紹了Android中創(chuàng)建快捷方式代碼實(shí)例,本文分為三個(gè)步驟實(shí)現(xiàn),并分別給出對(duì)應(yīng)實(shí)現(xiàn)代碼,需要的朋友可以參考下2015-04-04
9個(gè)非常棒的Android代碼編輯器 移動(dòng)開(kāi)發(fā)者的最?lèi)?ài)
這篇文章主要為大家分享了9個(gè)非常棒的Android代碼編輯器,據(jù)說(shuō)這可是移動(dòng)開(kāi)發(fā)者的最?lèi)?ài),知道是哪九個(gè)Android代碼編輯器2015-12-12

