首页 > 代码库 > 解释清楚智能指针一【用自己的话,解释清楚】

解释清楚智能指针一【用自己的话,解释清楚】

 

写在前面

用自己的话解释清楚~

 

智能指针是什么,可分为哪几种类型,各有什么特点,解决了什么问题,怎么解决的?

什么是智能指针?

智能指针是C++中的一个概念,主要是通过引用计数的方式,解决动态内存的自动释放问题(类似于Java Python中的垃圾回收)。主要解决程序常见的两个问题:动态的申请的内存没有释放;动态申请的内存释放后又被引用。

 

指针和引用的区别:

指针其实是一个变量,只不过它存储的是另一个变量的内存地址。而引用是另外一个变量的别名,它不占用空间。所以引用定义的时候必须初始化。引用访问对象是直接访问,指针访问对象是间接访问。

 

他们在源码中的位置

http://androidxref.com/4.4.3_r1.1/xref/frameworks/rs/cpp/util/RefBase.h

http://androidxref.com/4.4.3_r1.1/xref/frameworks/rs/server/RefBase.h

 

 

http://androidxref.com/4.4.3_r1.1/xref/system/core/libutils/RefBase.cpp

http://androidxref.com/4.4.3_r1.1/xref/system/core/include/utils/RefBase.h

 

据观察他们的实现,略有差异,不过对外功能是一致的。在此以前两者为例子。

Android  源码中设计了三个智能指针:

轻量化指针(Light Pointer)、强指针(Strong Pointer)和弱指针(Weak Pointer)。

各指针的特点

强指针:

它会记录对它所指对象的引用次数,当引用次数为0时,自动释放该内存。

弱指针:

它会保存所指向对象的地址。但要引用该对象时,需要先将弱指针升级为强指针,然后再引用。如果该对象已经释放,则升级失败。

 

 

轻量级指针源码分析:

 

163template <class T>

164class LightRefBase

165{

166public:

167    inline LightRefBase() : mCount(0) { }

168    inline void incStrong(__attribute__((unused)) const void* id) const {

169        __sync_fetch_and_add(&mCount, 1);

170    }

171    inline void decStrong(__attribute__((unused)) const void* id) const {

172        if (__sync_fetch_and_sub(&mCount, 1) == 1) {

173            delete static_cast<const T*>(this);

174        }

175    }

176    //! DEBUGGING ONLY: Get current strong ref count.

177    inline int32_t getStrongCount() const {

178        return mCount;

179    }

180

181    typedef LightRefBase<T> basetype;

182

183protected:

184    inline ~LightRefBase() { }

185

186private:

187    friend class ReferenceMover;

188    inline static void moveReferences(void*, void const*, size_t,

189            const ReferenceConverterBase&) { }

190

191private:

192    mutable volatile int32_t mCount;

193};

 

备注:

__sync_fetch_and_add()

__sync_fetch_and_sub()

用于增减mCount

 

无锁编程函数(参考文章:Multithreaded simple data type access and atomic variables)

__attribute__((unused))

 

在分析系统代码时注意到有些函数会有添加__attribute__((unused))

gcc手册中找到了有关的解释:

unusedThis attribute, attached to a function, means that the function is meant to be
        possibly unused. GCC will not produce a warning for this function.

======================================================================

used: This attribute, attached to a function, means that code must be emitted for the
       function even if it appears that the function is not referenced. This is useful,
       for example, when the function is referenced only in inline assembly.

表示该函数或变量可能不使用,这个属性可以避免编译器产生警告信息。

强弱指针源码分析

http://androidxref.com/4.4.3_r1.1/xref/system/core/include/utils/StrongPointer.h

 

29template<typename T> class wp;

//类似于普通类的声明,  这是一个模板类wp的声明,前面的template<typename T>  说//明它是一个模板类,用到的泛型类型  模板类中以T替代 

30

31//------------------------------------------------------------------

32

33#define COMPARE(_op_)                                           \

34inline bool operator _op_ (const sp<T>& o) const {              \

35    return m_ptr _op_ o.m_ptr;                                  \

36}      

                                                         \

37inline bool operator _op_ (const T* o) const {                  \

38    return m_ptr _op_ o;                                        \

39}                                                               \

40template<typename U>                                            \

41inline bool operator _op_ (const sp<U>& o) const {              \

42    return m_ptr _op_ o.m_ptr;                                  \

43}                                                               \

44template<typename U>                                            \

45inline bool operator _op_ (const U* o) const {                  \

46    return m_ptr _op_ o;                                        \

47}                                                               \

48inline bool operator _op_ (const wp<T>& o) const {              \

49    return m_ptr _op_ o.m_ptr;                                  \

50}                                                               \

51template<typename U>                                            \

52inline bool operator _op_ (const wp<U>& o) const {              \

53    return m_ptr _op_ o.m_ptr;                                  \

54}

55

56//-------------------------------------------------------------------

57

58template<typename T>

59class sp {

60public:

61    inline sp() : m_ptr(0) { }

62

63    sp(T* other);

64    sp(const sp<T>& other);

65    template<typename U> sp(U* other);

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

67

68    ~sp();

69

70    // Assignment

71

72    sp& operator = (T* other);

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

74

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

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

77

78    //! Special optimization for use by ProcessState (and nobody else).

79    void force_set(T* other);

80

81    // Reset

82

83    void clear();

84

85    // Accessors

86

87    inline  T&      operator* () const  { return *m_ptr; }

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

89    inline  T*      get() const         { return m_ptr; }

90

91    // Operators

92

93    COMPARE(==)

94    COMPARE(!=)

95    COMPARE(>)

96    COMPARE(<)

97    COMPARE(<=)

98    COMPARE(>=)

99

100private:

101    template<typename Y> friend class sp;

102    template<typename Y> friend class wp;

103    void set_pointer(T* ptr);

104    T* m_ptr;

105};

106

107#undef COMPARE

 

 

 

109//------------------------------------------------------------------

110// No user serviceable parts below here.

111

112template<typename T>

113sp<T>::sp(T* other)

114        : m_ptr(other) {

115    if (other)

116        other->incStrong(this);

117}

118

119template<typename T>

120sp<T>::sp(const sp<T>& other)

121        : m_ptr(other.m_ptr) {

122    if (m_ptr)

123        m_ptr->incStrong(this);

124}

125

126template<typename T> template<typename U>

127sp<T>::sp(U* other)

128        : m_ptr(other) {

129    if (other)

130        ((T*) other)->incStrong(this);

131}

132

133template<typename T> template<typename U>

134sp<T>::sp(const sp<U>& other)

135        : m_ptr(other.m_ptr) {

136    if (m_ptr)

137        m_ptr->incStrong(this);

138}

139

140template<typename T>

141sp<T>::~sp() {

142    if (m_ptr)

143        m_ptr->decStrong(this);

144}

145

146template<typename T>

147sp<T>& sp<T>::operator =(const sp<T>& other) {

148    T* otherPtr(other.m_ptr);

149    if (otherPtr)

150        otherPtr->incStrong(this);

151    if (m_ptr)

152        m_ptr->decStrong(this);

153    m_ptr = otherPtr;

154    return *this;

155}

156

157template<typename T>

158sp<T>& sp<T>::operator =(T* other) {

159    if (other)

160        other->incStrong(this);

161    if (m_ptr)

162        m_ptr->decStrong(this);

163    m_ptr = other;

164    return *this;

165}

166

167template<typename T> template<typename U>

168sp<T>& sp<T>::operator =(const sp<U>& other) {

169    T* otherPtr(other.m_ptr);

170    if (otherPtr)

171        otherPtr->incStrong(this);

172    if (m_ptr)

173        m_ptr->decStrong(this);

174    m_ptr = otherPtr;

175    return *this;

176}

177

178template<typename T> template<typename U>

179sp<T>& sp<T>::operator =(U* other) {

180    if (other)

181        ((T*) other)->incStrong(this);

182    if (m_ptr)

183        m_ptr->decStrong(this);

184    m_ptr = other;

185    return *this;

186}

187

188template<typename T>

189void sp<T>::force_set(T* other) {

190    other->forceIncStrong(this);

191    m_ptr = other;

192}

193

194template<typename T>

195void sp<T>::clear() {

196    if (m_ptr) {

197        m_ptr->decStrong(this);

198        m_ptr = 0;

199    }

200}

201

202template<typename T>

203void sp<T>::set_pointer(T* ptr) {

204    m_ptr = ptr;

205}

206

207}; // namespace android

208

209//----------------------------------------------------------------

 

Sp中可使用decStrong()等函数,是由于所有项使用强指针sp的类必须继承自RefBase类(decStrong()等函数  是RefBase类的成员函数)。

 

100private:

101    template<typename Y> friend class sp;

 

对这段代码的理解:

先说明一下友元类的作用

C++的设计中类的出现是为了提高程序的独立性和封装性。类中使用了关键字public private来定义了类中成员的访问权限,一般情况下,非类成员函数式不能访问类的内部成员函数或变量的。

但,有些情况可能需要这样,所以出C++的设计者设计了友元类这个类与类之间的关系,

它的特点是

  1. 是一个单向的关系,即定义了BA的友元类,并不代表AB的友元;
  2. 不具备传递性

 

这段代码中定义类模板类sp是模板类sp的友元类,是为了可以访问传递进来的其他类型的模板类sp的对象的私有成员变量(这里主要是m_ptr)。

比如重载的操作符==

40template<typename U>                                            \

41inline bool operator _op_ (const sp<U>& o) const {              \

42    return m_ptr _op_ o.m_ptr;       

 

如果没有定义为友元类,就不能访问传递进来的 对象o的私有变量o.m_ptr。

 

QQ群 计算机科学与艺术  272583193

加群链接:http://jq.qq.com/?_wv=1027&k=Q9OxMv