💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
我们首先分析LightRefBase类的实现原理,它的定义如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ 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; } protected: inline ~LightRefBase() { } private: mutable volatile int32_t mCount; }; ~~~ LightRefBase类是一个模板类,其中,模板参数T表示对象的实际类型,它必须是继承了LightRefBase类的。LightRefBase类只有一个成员变量mCount,用来描述一个对象的引用计数值。LightRefBase类同时提供了成员函数incStrong和decStrong来增加和减少它所引用的对象的引用计数。 > 注意:在成员函数decStrong中,如果对象的引用计数值在减少之后变成0,那么就表示需要释放这个对象所占用的内存了。 轻量级指针的实现类为sp,它同时也是强指针的实现类。在本节中,我们只关注它与轻量级指针相关的实现,它的定义如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ template <typename T> class sp { public: typedef typename RefBase::weakref_type weakref_type; 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; // Optimization for wp::promote(). sp(T* p, weakref_type* refs); T* m_ptr; }; ~~~ sp类也是一个模块类,其中,模板参数T表示对象的实际类型,它也是必须继承了LightRefBase类的。在sp类内部,使用RefBase::weakref_type类来维护它所引用的对象的强引用计数和弱引用计数,在3.2小节中分析强指针的实现原理时,我们再详细分析它。 sp类的实现比较复杂,但是与轻量级指针相关的部分只有成员变量m_ptr以及构造函数和析构函数。不难看出,sp类的成员变量m_ptr是一个指针,它是在构造函数里面初始化的,指向实际引用的对象。接下来我们就分析sp类的构造函数和析构函数的实现。 sp类的构造函数有两个版本,一个是普通的构造函数,一个是拷贝构造函数,如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ 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); } ~~~ 在这两个构造函数里面,首先都是初始化成员变量m_ptr,然后再调用它的成员函数incStrong来增加它的引用计数。由于成员变量m_ptr所指向的对象是从LightRefBase类继承下来的,因此,这两个构造函数实际上是调用了LightRefBase类的成员函数incStrong来增加对象的引用计数。 sp类的析构函数的实现如下所示。 **frameworks/base/include/utils/RefBase.h** ~~~ template<typename T> sp<T>::~sp() { if (m_ptr) m_ptr->decStrong(this); } ~~~ sp类的析构函数执行的操作刚好与构造函数相反,即调用成员变量m_ptr所指向的对象的成员函数decStrong来减少它的引用计数,实际上是调用LightRefBase类的成员函数decStrong来减少对象的引用计数。 至此,轻量级指针的实现原理就介绍完了。接下来我们通过一个实例来说明它的使用方法,以便加深对它的理解。