關於Android的輕指針

前言

之前對於c++語言不是特別熟悉,遇到很多問題,現在準備好好研究Android的系統,這裏好好研究下這個東西。其實這裏僅僅是用來記錄下自己的思路,這裏主要和Java語言比較,

正文

首先是輕指針,輕指針僅僅是用來記錄有多少指針指向當前向量,首先我們的需要一個接口,也就是一個基類,首先要定義一個mCount變量,可是如果我們在這個接口中直接對這個函數進行函數重載,或者友元的處理,就會影響當前類的一些操作,這裏我們大概用了一個類似Java中的工具類,讓工具類持有我們目標類的操作記錄然後記錄使用次數,這裏我們先來看下這個基類,

template <class T>
class LightRefBase  //這是一個模板類,類似接口。
{
public:
    inline LightRefBase() : mCount(0) { }   //構造函數,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:
    inline ~LightRefBase() { }

private:
    friend class ReferenceMover;
    inline static void moveReferences(void*, void const*, size_t,
            const ReferenceConverterBase&) { }

private:
    mutable volatile int32_t mCount;
};

同時這也是一個模板類,這樣可以不用集成,即可讓你的類擁有了輕指針的特性,至於模板類,當然是爲了爲了清理內存,因爲我們的類沒如果想從內存中消除需要知道是哪個類,這裏其實沒什麼複雜的,早incStrong,和decStrong,這裏不要過分裏面Gcc特特性,基本可以無視,知道是增加指針計數,和減少指針計數。至於哪個工具類,sp,就不比較複雜了,這裏我們不要關注裏面的東西,只要知道大概遠離即可,我也不想過分在c++特性糾結,畢竟比較複雜,特別是操作符的複寫和友元的使用。

template <typename T>
class sp
{
public:
    inline sp() : m_ptr(0) { }

    sp(T* other);
    sp(const sp<T>& other);
    template<typename U> sp(U* other);
    template<typename U> sp(const sp<U>& other);

    ~sp();

    // Assignment

    sp& operator = (T* other);
    sp& operator = (const sp<T>& other);

    template<typename U> sp& operator = (const sp<U>& other);
    template<typename U> sp& operator = (U* other);

    //! Special optimization for use by ProcessState (and nobody else).
    void force_set(T* other);

    // Reset

    void clear();

    // Accessors

    inline  T&      operator* () const  { return *m_ptr; }
    inline  T*      operator-> () const { return m_ptr;  }
    inline  T*      get() const         { return m_ptr; }

    // Operators

    COMPARE(==)
    COMPARE(!=)
    COMPARE(>)
    COMPARE(<)
    COMPARE(<=)
    COMPARE(>=)

private:
    template<typename Y> friend class sp;
    template<typename Y> friend class wp;
    void set_pointer(T* ptr);
    T* m_ptr;
};

這裏我們只要知道,關注下構造函數:

template<typename T>
sp<T>::sp(T* other)
: m_ptr(other)
  {
    if (other) other->incStrong(this);
  }

template<typename T>
sp<T>::sp(const sp<T>& other)
: m_ptr(other.m_ptr)
  {
    if (m_ptr) m_ptr->incStrong(this);
  }

template<typename T> template<typename U>
sp<T>::sp(U* other) : m_ptr(other)
{
    if (other) ((T*)other)->incStrong(this);
}

template<typename T> template<typename U>
sp<T>::sp(const sp<U>& other)
: m_ptr(other.m_ptr)
  {
    if (m_ptr) m_ptr->incStrong(this);
  }

template<typename T>
sp<T>::~sp()
{
    if (m_ptr) m_ptr->decStrong(this);
}

其實只要關心第一構造函數,也就是讓這個m_ptr指向我們需要用輕指針控制的變量,至於類的註銷,當然調用真正需要管理的那個類的decStrong函數來處理,至於其中的友元的等號,其他操作符的重載,這裏我暫時不研究,
至於使用,這裏我先介紹下

class LightClass : public LightRefBase<lightClass>
{
}
void main(){
sp(LightClass) light_class = new LightClass();
{
    sp(LightClass) inner= new LightClass();
}
}

這裏來了一個最簡單的使用,當我們進入內部時候,我們的mCount計數爲2,具體也不在驗證,這裏瞭解大概流程,sp其實就像是Java的Unti類,便於操作,這裏就到這裏,

後記

之前對於這個邏輯感覺好難受,現在感覺這裏基本邏輯都挺正常,這裏當成我的一個筆記,之後再研究強指針。

發佈了66 篇原創文章 · 獲贊 29 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章