为什么会引入智能指针?——弥补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
};