andoid的智能指针

来源:互联网 发布:和明星合影软件 编辑:程序博客网 时间:2024/05/01 03:44

        为什么会引入智能指针?——弥补C++代码的指针问题。这是主要目的。

        智能指针是一种能够自动维护对象引用计数的技术。智能指针本身并不是指针,它是一个对象,但是它引用了一个世纪使用的对象。因为它是一个对象,所以它可以自动地维护实际对象的引用技术——在智能指针构造时,增加它对所引用的对象的引用计数;在智能指针析构时,就减少它所引用的对象的引用计数。由于智能指针的构造和析构都是自动的,所以就自动地实现了对象的引用计数。

       为了解决相互引用死锁导致两个对象不能被释放的问题,引入了强制针和弱指针。

      android系统引入了三种智能指针类型:轻量级指针(Light Pointer)、强指针(Strong Pointer)和弱指针(Weak Pointer)。

      一个对象的弱引用计数一定是大于或者是等于它的强引用计数。

      弱指针和强指针最大的区别是:弱指针不可以直接操作它所引用的对象。因为它所引用的对象可能是不受弱引用计数控制的,即它所引用的对象可能是一个无效的对象。因此,如果需要操作一个弱指针所引用的对象,那么就需要将这个弱指针升级为强指针,通过成员函数promote来实现的。如果升级成功,就说明该弱指针所引用的对象还没有被销毁,还可以正常使用。

       轻量级指针的原始基类是LightRefBase。

// ---------------------------------------------------------------------------template <class T>class LightRefBase{public:    inline LightRefBase() : mCount(0) { }    inline void incStrong(const void* id) const {        android_atomic_inc(&mCount);    }    inline void decStrong(const void* id) const {        if (android_atomic_dec(&mCount) == 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* d, void const* s, size_t n,            const ReferenceConverterBase& caster) { }private:    mutable volatile int32_t mCount;};


       强指针和弱指针的原始基类是RefBase.

 

// ---------------------------------------------------------------------------class RefBase{public:            void            incStrong(const void* id) const;            void            decStrong(const void* id) const;                void            forceIncStrong(const void* id) const;            //! DEBUGGING ONLY: Get current strong ref count.            int32_t         getStrongCount() const;    class weakref_type    {    public:        RefBase*            refBase() const;                void                incWeak(const void* id);        void                decWeak(const void* id);                // acquires a strong reference if there is already one.        bool                attemptIncStrong(const void* id);                // acquires a weak reference if there is already one.        // This is not always safe. see ProcessState.cpp and BpBinder.cpp        // for proper use.        bool                attemptIncWeak(const void* id);        //! DEBUGGING ONLY: Get current weak ref count.        int32_t             getWeakCount() const;        //! DEBUGGING ONLY: Print references held on object.        void                printRefs() const;        //! DEBUGGING ONLY: Enable tracking for this object.        // enable -- enable/disable tracking        // retain -- when tracking is enable, if true, then we save a stack trace        //           for each reference and dereference; when retain == false, we        //           match up references and dereferences and keep only the         //           outstanding ones.                void                trackMe(bool enable, bool retain);    };                weakref_type*   createWeak(const void* id) const;                        weakref_type*   getWeakRefs() const;            //! DEBUGGING ONLY: Print references held on object.    inline  void            printRefs() const { getWeakRefs()->printRefs(); }            //! DEBUGGING ONLY: Enable tracking of object.    inline  void            trackMe(bool enable, bool retain)    {         getWeakRefs()->trackMe(enable, retain);     }    typedef RefBase basetype;protected:                            RefBase();    virtual                 ~RefBase();    //! Flags for extendObjectLifetime()    enum {        OBJECT_LIFETIME_STRONG  = 0x0000,        OBJECT_LIFETIME_WEAK    = 0x0001,        OBJECT_LIFETIME_MASK    = 0x0001    };                void            extendObjectLifetime(int32_t mode);                //! Flags for onIncStrongAttempted()    enum {        FIRST_INC_STRONG = 0x0001    };        virtual void            onFirstRef();    virtual void            onLastStrongRef(const void* id);    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);    virtual void            onLastWeakRef(const void* id);private:    friend class ReferenceMover;    static void moveReferences(void* d, void const* s, size_t n,            const ReferenceConverterBase& caster);private:    friend class weakref_type;    class weakref_impl;                                RefBase(const RefBase& o);            RefBase&        operator=(const RefBase& o);        weakref_impl* const mRefs; //真正用来描述对象的引用计数的};

 

      weakref_impl类继承于weakref_type类。

// ---------------------------------------------------------------------------class RefBase::weakref_impl : public RefBase::weakref_type{public:    volatile int32_t    mStrong; //对象的强引用计数    volatile int32_t    mWeak; //对象的弱引用计数    RefBase* const      mBase;  //所引用对象的地址    volatile int32_t    mFlags; //标志值:描述对象的生命周期控制方式    //mFlags取值范围:OBJECT_LIFETIME_STRONG、OBJECT_LIFETIME_WEAK、OBJECT_LIFETIME_MASK    //OBJECT_LIFETIME_STRONG:表示对象的生命周期只受强引用计数影响    //OBJECT_LIFETIME_WEAK:表示对象的生命周期同时受强引用计数和弱引用计数影响    //OBJECT_LIFETIME_MASK:表示对象的生命周期完全不受强引用计数或者弱引用计数的影响,回归到C++本身#if !DEBUG_REFS    weakref_impl(RefBase* base)        : mStrong(INITIAL_STRONG_VALUE)        , mWeak(0)        , mBase(base)        , mFlags(0)    {    }    void addStrongRef(const void* /*id*/) { }    void removeStrongRef(const void* /*id*/) { }    void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }    void addWeakRef(const void* /*id*/) { }    void removeWeakRef(const void* /*id*/) { }    void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }    void printRefs() const { }    void trackMe(bool, bool) { }#else    ... ...#endif};


  

 

 

原创粉丝点击