1. 智能指针是一个包装类,该类有一个指针指向真正的类对象
  2. 引用计数型智能指针,该引用计数是在应该被真正类所持有,而非包装类(智能指针)
  3. 为了方便,会将引用计数单独实现在一个类中,这样所有继承它的类都有计数器
  1. // ---------------------------------------------------------------------------
  2.  
  3. template <typename T>
  4. class sp
  5. {
  6. public:
  7. inline sp() : m_ptr(0) { }
  8.  
  9. sp(T* other);
  10. sp(const sp<T>& other);
  11. template<typename U> sp(U* other);
  12. template<typename U> sp(const sp<U>& other);
  13.  
  14. ~sp();
  15.  
  16. // Assignment
  17.  
  18. sp& operator = (T* other);
  19. sp& operator = (const sp<T>& other);
  20.  
  21. template<typename U> sp& operator = (const sp<U>& other);
  22. template<typename U> sp& operator = (U* other);
  23. void force_set(T* other);
  24.  
  25. // Reset
  26.  
  27. void clear();
  28.  
  29. // Accessors
  30.  
  31. inline T& operator* () const { return *m_ptr; }//重写操作符,获取真正的对象
  32. inline T* operator-> () const { return m_ptr; }
  33. inline T* get() const { return m_ptr; }
  34.  
  35. // Operators
  36.  
  37. COMPARE(==)
  38. COMPARE(!=)
  39. COMPARE(>)
  40. COMPARE(<)
  41. COMPARE(<=)
  42. COMPARE(>=)
  43.  
  44. private:
  45. template<typename Y> friend class sp;
  46. template<typename Y> friend class wp;
  47. void set_pointer(T* ptr);
  48. T* m_ptr;//指向真正的类对象的指针
  49. };

  

  1. // ---------------------------------------------------------------------------
  2.  
  3. class RefBase//所有继承该类的类都持有一个计数器
  4. {
  5. public:
  6. void incStrong(const void* id) const;
  7. void decStrong(const void* id) const;
  8.  
  9. void forceIncStrong(const void* id) const;
  10.  
  11. //! DEBUGGING ONLY: Get current strong ref count.
  12. int32_t getStrongCount() const;
  13.  
  14. class weakref_type//这相当于那个计数器
  15. {
  16. public:
  17. RefBase* refBase() const;
  18.  
  19. void incWeak(const void* id);
  20. void decWeak(const void* id);
  21.  
  22. // acquires a strong reference if there is already one.
  23. bool attemptIncStrong(const void* id);
  24.  
  25. // acquires a weak reference if there is already one.
  26. // This is not always safe. see ProcessState.cpp and BpBinder.cpp
  27. // for proper use.
  28. bool attemptIncWeak(const void* id);
  29.  
  30. //! DEBUGGING ONLY: Get current weak ref count.
  31. int32_t getWeakCount() const;
  32.  
  33. //! DEBUGGING ONLY: Print references held on object.
  34. void printRefs() const;
  35.  
  36. void trackMe(bool enable, bool retain);
  37. };
  38.  
  39. weakref_type* createWeak(const void* id) const;
  40.  
  41. weakref_type* getWeakRefs() const;
  42.  
  43. //! DEBUGGING ONLY: Print references held on object.
  44. inline void printRefs() const { getWeakRefs()->printRefs(); }
  45.  
  46. //! DEBUGGING ONLY: Enable tracking of object.
  47. inline void trackMe(bool enable, bool retain)
  48. {
  49. getWeakRefs()->trackMe(enable, retain);
  50. }
  51.  
  52. typedef RefBase basetype;
  53.  
  54. protected:
  55. RefBase();
  56. virtual ~RefBase();
  57.  
  58. //! Flags for extendObjectLifetime()
  59. enum {
  60. OBJECT_LIFETIME_STRONG = 0x0000,
  61. OBJECT_LIFETIME_WEAK = 0x0001,
  62. OBJECT_LIFETIME_MASK = 0x0001
  63. };
  64.  
  65. void extendObjectLifetime(int32_t mode);
  66.  
  67. //! Flags for onIncStrongAttempted()
  68. enum {
  69. FIRST_INC_STRONG = 0x0001
  70. };
  71.  
  72. virtual void onFirstRef();
  73. virtual void onLastStrongRef(const void* id);
  74. virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
  75. virtual void onLastWeakRef(const void* id);
  76.  
  77. private:
  78. friend class ReferenceMover;
  79. static void moveReferences(void* d, void const* s, size_t n,
  80. const ReferenceConverterBase& caster);
  81.  
  82. private:
  83. friend class weakref_type;
  84. class weakref_impl;
  85.  
  86. RefBase(const RefBase& o);
  87. RefBase& operator=(const RefBase& o);
  88.  
  89. weakref_impl* const mRefs;
  90. };

  1. // ---------------------------------------------------------------------------
  2.  
  3. class RefBase::weakref_impl : public RefBase::weakref_type//引用计数器的实现类
  4. {
  5. public:
  6. volatile int32_t mStrong;//强引用
  7. volatile int32_t mWeak;//若引用
  8. RefBase* const mBase;
  9. volatile int32_t mFlags;
  10.  
  11. #if !DEBUG_REFS
  12.  
  13. weakref_impl(RefBase* base)
  14. : mStrong(INITIAL_STRONG_VALUE)
  15. , mWeak(0)
  16. , mBase(base)
  17. , mFlags(0)
  18. {
  19. }
  20.  
  21. void addStrongRef(const void* /*id*/) { }
  22. void removeStrongRef(const void* /*id*/) { }
  23. void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { }
  24. void addWeakRef(const void* /*id*/) { }
  25. void removeWeakRef(const void* /*id*/) { }
  26. void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { }
  27. void printRefs() const { }
  28. void trackMe(bool, bool) { }
  29.  
  30. #else
  31.  
  32. weakref_impl(RefBase* base)
  33. : mStrong(INITIAL_STRONG_VALUE)
  34. , mWeak(0)
  35. , mBase(base)
  36. , mFlags(0)
  37. , mStrongRefs(NULL)
  38. , mWeakRefs(NULL)
  39. , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT)
  40. , mRetain(false)
  41. {
  42. }
  43.  
  44. ~weakref_impl()
  45. {
  46. bool dumpStack = false;
  47. if (!mRetain && mStrongRefs != NULL) {
  48. dumpStack = true;
  49. #if DEBUG_REFS_FATAL_SANITY_CHECKS
  50. LOG_ALWAYS_FATAL("Strong references remain!");
  51. #else
  52. ALOGE("Strong references remain:");
  53. #endif
  54. ref_entry* refs = mStrongRefs;
  55. while (refs) {
  56. char inc = refs->ref >= 0 ? '+' : '-';
  57. ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
  58. #if DEBUG_REFS_CALLSTACK_ENABLED
  59. refs->stack.dump();
  60. #endif
  61. refs = refs->next;
  62. }
  63. }
  64.  
  65. if (!mRetain && mWeakRefs != NULL) {
  66. dumpStack = true;
  67. #if DEBUG_REFS_FATAL_SANITY_CHECKS
  68. LOG_ALWAYS_FATAL("Weak references remain:");
  69. #else
  70. ALOGE("Weak references remain!");
  71. #endif
  72. ref_entry* refs = mWeakRefs;
  73. while (refs) {
  74. char inc = refs->ref >= 0 ? '+' : '-';
  75. ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref);
  76. #if DEBUG_REFS_CALLSTACK_ENABLED
  77. refs->stack.dump();
  78. #endif
  79. refs = refs->next;
  80. }
  81. }
  82. if (dumpStack) {
  83. ALOGE("above errors at:");
  84. CallStack stack;
  85. stack.update();
  86. stack.dump();
  87. }
  88. }
  89.  
  90. void addStrongRef(const void* id) {
  91. //ALOGD_IF(mTrackEnabled,
  92. // "addStrongRef: RefBase=%p, id=%p", mBase, id);
  93. addRef(&mStrongRefs, id, mStrong);
  94. }
  95.  
  96. void removeStrongRef(const void* id) {
  97. //ALOGD_IF(mTrackEnabled,
  98. // "removeStrongRef: RefBase=%p, id=%p", mBase, id);
  99. if (!mRetain) {
  100. removeRef(&mStrongRefs, id);
  101. } else {
  102. addRef(&mStrongRefs, id, -mStrong);
  103. }
  104. }
  105.  
  106. void renameStrongRefId(const void* old_id, const void* new_id) {
  107. //ALOGD_IF(mTrackEnabled,
  108. // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p",
  109. // mBase, old_id, new_id);
  110. renameRefsId(mStrongRefs, old_id, new_id);
  111. }
  112.  
  113. void addWeakRef(const void* id) {
  114. addRef(&mWeakRefs, id, mWeak);
  115. }
  116.  
  117. void removeWeakRef(const void* id) {
  118. if (!mRetain) {
  119. removeRef(&mWeakRefs, id);
  120. } else {
  121. addRef(&mWeakRefs, id, -mWeak);
  122. }
  123. }
  124.  
  125. void renameWeakRefId(const void* old_id, const void* new_id) {
  126. renameRefsId(mWeakRefs, old_id, new_id);
  127. }
  128.  
  129. void trackMe(bool track, bool retain)
  130. {
  131. mTrackEnabled = track;
  132. mRetain = retain;
  133. }
  134.  
  135. void printRefs() const
  136. {
  137. String8 text;
  138.  
  139. {
  140. Mutex::Autolock _l(mMutex);
  141. char buf[128];
  142. sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this);
  143. text.append(buf);
  144. printRefsLocked(&text, mStrongRefs);
  145. sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this);
  146. text.append(buf);
  147. printRefsLocked(&text, mWeakRefs);
  148. }
  149.  
  150. {
  151. char name[100];
  152. snprintf(name, 100, "/data/%p.stack", this);
  153. int rc = open(name, O_RDWR | O_CREAT | O_APPEND);
  154. if (rc >= 0) {
  155. write(rc, text.string(), text.length());
  156. close(rc);
  157. ALOGD("STACK TRACE for %p saved in %s", this, name);
  158. }
  159. else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this,
  160. name, strerror(errno));
  161. }
  162. }
  163.  
  164. private:
  165. struct ref_entry
  166. {
  167. ref_entry* next;
  168. const void* id;
  169. #if DEBUG_REFS_CALLSTACK_ENABLED
  170. CallStack stack;
  171. #endif
  172. int32_t ref;
  173. };
  174.  
  175. void addRef(ref_entry** refs, const void* id, int32_t mRef)
  176. {
  177. if (mTrackEnabled) {
  178. AutoMutex _l(mMutex);
  179.  
  180. ref_entry* ref = new ref_entry;
  181. // Reference count at the time of the snapshot, but before the
  182. // update. Positive value means we increment, negative--we
  183. // decrement the reference count.
  184. ref->ref = mRef;
  185. ref->id = id;
  186. #if DEBUG_REFS_CALLSTACK_ENABLED
  187. ref->stack.update(2);
  188. #endif
  189. ref->next = *refs;
  190. *refs = ref;
  191. }
  192. }
  193.  
  194. void removeRef(ref_entry** refs, const void* id)
  195. {
  196. if (mTrackEnabled) {
  197. AutoMutex _l(mMutex);
  198.  
  199. ref_entry* const head = *refs;
  200. ref_entry* ref = head;
  201. while (ref != NULL) {
  202. if (ref->id == id) {
  203. *refs = ref->next;
  204. delete ref;
  205. return;
  206. }
  207. refs = &ref->next;
  208. ref = *refs;
  209. }
  210.  
  211. #if DEBUG_REFS_FATAL_SANITY_CHECKS
  212. LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p"
  213. "(weakref_type %p) that doesn't exist!",
  214. id, mBase, this);
  215. #endif
  216.  
  217. ALOGE("RefBase: removing id %p on RefBase %p"
  218. "(weakref_type %p) that doesn't exist!",
  219. id, mBase, this);
  220.  
  221. ref = head;
  222. while (ref) {
  223. char inc = ref->ref >= 0 ? '+' : '-';
  224. ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref);
  225. ref = ref->next;
  226. }
  227.  
  228. CallStack stack;
  229. stack.update();
  230. stack.dump();
  231. }
  232. }
  233.  
  234. void renameRefsId(ref_entry* r, const void* old_id, const void* new_id)
  235. {
  236. if (mTrackEnabled) {
  237. AutoMutex _l(mMutex);
  238. ref_entry* ref = r;
  239. while (ref != NULL) {
  240. if (ref->id == old_id) {
  241. ref->id = new_id;
  242. }
  243. ref = ref->next;
  244. }
  245. }
  246. }
  247.  
  248. void printRefsLocked(String8* out, const ref_entry* refs) const
  249. {
  250. char buf[128];
  251. while (refs) {
  252. char inc = refs->ref >= 0 ? '+' : '-';
  253. sprintf(buf, "\t%c ID %p (ref %d):\n",
  254. inc, refs->id, refs->ref);
  255. out->append(buf);
  256. #if DEBUG_REFS_CALLSTACK_ENABLED
  257. out->append(refs->stack.toString("\t\t"));
  258. #else
  259. out->append("\t\t(call stacks disabled)");
  260. #endif
  261. refs = refs->next;
  262. }
  263. }
  264.  
  265. mutable Mutex mMutex;
  266. ref_entry* mStrongRefs;
  267. ref_entry* mWeakRefs;
  268.  
  269. bool mTrackEnabled;
  270. // Collect stack traces on addref and removeref, instead of deleting the stack references
  271. // on removeref that match the address ones.
  272. bool mRetain;
  273.  
  274. #endif
  275. };

  

  小结:

  1. 通常情况下,智能指针分为sp和wp
  2. 目标对象的父类是RefBase——这个基类提供了一个weakref_impl类型的引用计数器,可以同时进行强弱引用的控制

android分析之智能指针的更多相关文章

  1. Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6786239 Android 系统的运行时库层代 ...

  2. ZT自老罗的博客 Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 分类: Android 2011-09-23 00:59 31568人阅读 评论(42) 收藏 举报 androidclass ...

  3. Android系统智能指针的设计思路(轻量级指针、强指针、弱指针)

    本博客为原创,转载请注明出处,谢谢. 参考博文:Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 C++中最容易出错的地方莫过于指针了,指针问题主要有两类,一是内存泄露,二是无 ...

  4. Android智能指针SP WP使用方法介绍

    Android手机操作系统既然是开源的操作系统.那么在具体的文件夹中就会存放着各种相关功能的开源代码.我们在使用的时候可以根据这些源代码进行相应的修改就能轻松的完成我们所需的功能.在这里大家就一起来看 ...

  5. c++智能指针介绍_补充

    不明白我做错了什么,这几天老婆给我冷战了起来,也不给我开视频让我看娃了..哎,心累!趁着今晚的一些空闲时间来对智能指针做个补充吧. 写完上篇“智能指针介绍”后,第二天上班途中时,突然一个疑问盘踞在心头 ...

  6. React Native 4 for Android源码分析 一《JNI智能指针之介绍篇》

    文/ Tamic: http://blog.csdn.net/sk719887916/article/details/53455441 原文:http://blog.csdn.net/eewolf/a ...

  7. Android结构分析Android智能指针(两)

    笔者:刘蒿羽 博客:http://blog.csdn.net/liuhaoyutz Android版本号:4.4.2 在上一篇文章中,我们分析了Android智能指针中的强指针sp,本文我们来分析弱指 ...

  8. Android智能指针sp wp详解

    研究Android的时候,经常会遇到sp.wp的东西,网上一搜,原来是android封装了c++中对象回收机制.说明:1. 如果一个类想使用智能指针,那么必须满足下面两个条件:    a. 该类是虚基 ...

  9. ReactNative 4Android源码分析二: 《JNI智能指针之实现篇》

    文/Tamic http://blog.csdn.net/sk719887916/article/details/53462268 回顾 上一篇介绍了<ReactNative4Android源码 ...

随机推荐

  1. Leetcode(878)-第 N 个神奇数字

    如果正整数可以被 A 或 B 整除,那么它是神奇的. 返回第 N 个神奇数字.由于答案可能非常大,返回它模 10^9 + 7 的结果. 示例 1: 输入:N = 1, A = 2, B = 3 输出: ...

  2. bzoj1013球形空间产生器sphere 高斯消元(有系统差的写法

    Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁 ...

  3. Python爬虫全网搜索并下载音乐

    现在写一篇博客总是喜欢先谈需求或者本内容的应用场景,是的,如果写出来的东西没有任何应用价值,确实也没有实际意义.今天的最早的需求是来自于如何免费[白嫖]下载全网优质音乐,我去b站上面搜索到了一个大牛做 ...

  4. Web 安全漏洞 All In One

    Web 安全漏洞 All In One Web 安全 & 漏洞 输入输出验证不充分 SQL 注入 XSS self-XSS CSRF 目录穿越 文件上传 代码注入 命令注入 信息漏洞 暴力破解 ...

  5. Swift 5.3 All In One

    Swift 5.3 All In One refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!

  6. 海 鱼立 鲷 & 海䲞鲷

    海 鱼立 鲷 & 海䲞鲷 䲞 lì 鲷 diāo 二长棘鲷 二长棘鲷(学名:Parargyrops edita)为辐鳍鱼纲鲈形目鲷科二长棘鲷属的鱼类,俗名板鱼.䲞鱼.盘仔鱼.立花.赤鬃.长鳍. ...

  7. Android Studio & Flutter Plugins & Dart plugins

    Android Studio & Flutter Plugins & Dart plugins https://flutter.dev/docs/get-started/editor? ...

  8. how to group date array by month in javascript

    how to group date array by month in javascript https://stackoverflow.com/questions/14446511/most-eff ...

  9. 第44天学习打卡(JUC 线程和进程 并发和并行 Lock锁 生产者和消费者问题 如何判断锁(8锁问题) 集合类不安全)

    什么是JUC 1.java.util工具包 包 分类 业务:普通的线程代码 Thread Runnable 没有返回值.效率相比Callable相对较低 2.线程和进程 进程:一个程序.QQ.exe, ...

  10. GetQueuedCompletionStatus客户端前端和server之间的通信

    项目中遇到了这个东西,怎么都调试不到.记录下. 一.完成端口IOCP https://www.cnblogs.com/yuanchenhui/p/iocp_windows.html