juce中的WeakReference设计得比较巧妙,巧妙就是使用delete之后就可以通知道WeakReference,原理其实也很间单,其实就是在对象里添加了一个子对象masterReference,对象在析构的时候主动调用masterReference.clear();,这样来达到通知弱指针的这个对象已经销毁了,可以设置为空了的目的。 感觉juce最后调用个clear还是觉得有点生硬,外层最好还是再嵌套一层,析构的时候自动调用clear就可以了,对象申明也写成宏,这样的话就简洁多了。

使用方法也很简单:

  1. /==============================================================================
  2. /**
  3. This class acts as a pointer which will automatically become null if the object
  4. to which it points is deleted.
  5.  
  6. To accomplish this, the source object needs to cooperate by performing a couple of simple tasks.
  7. It must embed a WeakReference::Master object, which stores a shared pointer object, and must clear
  8. this master pointer in its destructor.
  9.  
  10. E.g.
  11. @code
  12. class MyObject
  13. {
  14. public:
  15. MyObject()
  16. {
  17. // If you're planning on using your WeakReferences in a multi-threaded situation, you may choose
  18. // to create a WeakReference to the object here in the constructor, which will pre-initialise the
  19. // embedded object, avoiding an (extremely unlikely) race condition that could occur if multiple
  20. // threads overlap while creating the first WeakReference to it.
  21. }
  22.  
  23. ~MyObject()
  24. {
  25. // This will zero all the references - you need to call this in your destructor.
  26. masterReference.clear();
  27. }
  28.  
  29. private:
  30. // You need to embed a variable of this type, with the name "masterReference" inside your object. If the
  31. // variable is not public, you should make your class a friend of WeakReference<MyObject> so that the
  32. // WeakReference class can access it.
  33. WeakReference<MyObject>::Master masterReference;
  34. friend class WeakReference<MyObject>;
  35. };
  36.  
  37. // Here's an example of using a pointer..
  38.  
  39. MyObject* n = new MyObject();
  40. WeakReference<MyObject> myObjectRef = n;
  41.  
  42. MyObject* pointer1 = myObjectRef; // returns a valid pointer to 'n'
  43. delete n;
  44. MyObject* pointer2 = myObjectRef; // returns a null pointer
  45. @endcode
  46.  
  47. @see WeakReference::Master
  48. */

源码如下:

  1. #ifndef JUCE_WEAKREFERENCE_H_INCLUDED
  2. #define JUCE_WEAKREFERENCE_H_INCLUDED
  3.  
  4. /
  5. template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>
  6. class WeakReference
  7. {
  8. public:
  9. /** Creates a null SafePointer. */
  10. inline WeakReference() noexcept {}
  11.  
  12. /** Creates a WeakReference that points at the given object. */
  13. WeakReference (ObjectType* const object) : holder (getRef (object)) {}
  14.  
  15. /** Creates a copy of another WeakReference. */
  16. WeakReference (const WeakReference& other) noexcept : holder (other.holder) {}
  17.  
  18. /** Copies another pointer to this one. */
  19. WeakReference& operator= (const WeakReference& other) { holder = other.holder; return *this; }
  20.  
  21. /** Copies another pointer to this one. */
  22. WeakReference& operator= (ObjectType* const newObject) { holder = getRef (newObject); return *this; }
  23.  
  24. #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS
  25. WeakReference (WeakReference&& other) noexcept : holder (static_cast<SharedRef&&> (other.holder)) {}
  26. WeakReference& operator= (WeakReference&& other) noexcept { holder = static_cast<SharedRef&&> (other.holder); return *this; }
  27. #endif
  28.  
  29. /** Returns the object that this pointer refers to, or null if the object no longer exists. */
  30. ObjectType* get() const noexcept { return holder != nullptr ? holder->get() : nullptr; }
  31.  
  32. /** Returns the object that this pointer refers to, or null if the object no longer exists. */
  33. operator ObjectType*() const noexcept { return get(); }
  34.  
  35. /** Returns the object that this pointer refers to, or null if the object no longer exists. */
  36. ObjectType* operator->() noexcept { return get(); }
  37.  
  38. /** Returns the object that this pointer refers to, or null if the object no longer exists. */
  39. const ObjectType* operator->() const noexcept { return get(); }
  40.  
  41. /** This returns true if this reference has been pointing at an object, but that object has
  42. since been deleted.
  43.  
  44. If this reference was only ever pointing at a null pointer, this will return false. Using
  45. operator=() to make this refer to a different object will reset this flag to match the status
  46. of the reference from which you're copying.
  47. */
  48. bool wasObjectDeleted() const noexcept { return holder != nullptr && holder->get() == nullptr; }
  49.  
  50. bool operator== (ObjectType* const object) const noexcept { return get() == object; }
  51. bool operator!= (ObjectType* const object) const noexcept { return get() != object; }
  52.  
  53. //==============================================================================
  54. /** This class is used internally by the WeakReference class - don't use it directly
  55. in your code!
  56. @see WeakReference,
  57. */
  58. class SharedPointer : public ReferenceCountingType
  59. {
  60. public:
  61. explicit SharedPointer (ObjectType* const obj) noexcept : owner (obj) {}
  62.  
  63. inline ObjectType* get() const noexcept { return owner; }
  64. void clearPointer() noexcept { owner = nullptr; }
  65.  
  66. private:
  67. ObjectType* volatile owner;
  68.  
  69. JUCE_DECLARE_NON_COPYABLE (SharedPointer)
  70. };
  71.  
  72. typedef ReferenceCountedObjectPtr<SharedPointer> SharedRef;
  73.  
  74. //==============================================================================
  75. /**
  76. This class is embedded inside an object to which you want to attach WeakReference pointers.
  77. See the WeakReference class notes for an example of how to use this class.
  78. @see WeakReference
  79. */
  80. class Master
  81. {
  82. public:
  83. Master() noexcept {}
  84.  
  85. ~Master() noexcept
  86. {
  87. // You must remember to call clear() in your source object's destructor! See the notes
  88. // for the WeakReference class for an example of how to do this.
  89. jassert (sharedPointer == nullptr || sharedPointer->get() == nullptr);
  90. }
  91.  
  92. /** The first call to this method will create an internal object that is shared by all weak
  93. references to the object.
  94. */
  95. SharedPointer* getSharedPointer (ObjectType* const object)
  96. {
  97. if (sharedPointer == nullptr)
  98. {
  99. //先用智能指针给包装起来
  100. sharedPointer = new SharedPointer (object);
  101. }
  102. else
  103. {
  104. // You're trying to create a weak reference to an object that has already been deleted!!
  105. jassert (sharedPointer->get() != nullptr);
  106. }
  107.  
  108. return sharedPointer;
  109. }
  110.  
  111. /** The object that owns this master pointer should call this before it gets destroyed,
  112. to zero all the references to this object that may be out there. See the WeakReference
  113. class notes for an example of how to do this.
  114. */
  115. void clear() noexcept
  116. {
  117. if (sharedPointer != nullptr)
  118. sharedPointer->clearPointer();
  119. }
  120.  
  121. private:
  122. SharedRef sharedPointer;
  123.  
  124. JUCE_DECLARE_NON_COPYABLE (Master)
  125. };
  126.  
  127. private:
  128. SharedRef holder;

  129.   //这里看出取得了object里的masterReference,所以使用的对象必需要包含这个成员,getSharedPointer返回一个SharedPointer的智能指针,而SharedPointer里包装了真正的对象的指针,由于SharedPointer被智能指针包着,所以弱引用的对象被删除了,这个
  1.   SharedPointer仍然存在,但它里面的指针对象由于clear被设置为null,这里再调用get自然就知道对象是否被删除
  1. static inline SharedPointer* getRef (ObjectType* const o) { return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr; } }; #endif // JUCE_WEAKREFERENCE_H_INCLUDED

  

juce 中的WeakReference分析的更多相关文章

  1. juce中的BailOutChecker

    界面库中值得注意的一点就是对象响应事件的时候自身被删除了,那么后续的访问自然就会出问题,所以需要在响应事件之后先添加引用,相关处理之后再查看自身是否已经被删除,如果已经被删除那么就直接退出.juce中 ...

  2. juce中的timer

    juce中timer总体说还是比较好用的,使用时只需继承timer类, 重写callback然后调用start就可以了,juce的timer比较特别,自己通过线程实现,starttimer的时候会创建 ...

  3. Android中AppWidget的分析与应用:AppWidgetProvider .

    from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...

  4. JAVA WEB 中的编码分析

    JAVA WEB 中的编码分析 */--> pre.src {background-color: #292b2e; color: #b2b2b2;} pre.src {background-co ...

  5. Android 中图片压缩分析(上)

    作者: shawnzhao,QQ音乐技术团队一员 一.前言 在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩. 前者是在不改变图片尺寸的情 ...

  6. 《构建之法》教学笔记——Python中的效能分析与几个问题

    <构建之法:现代软件工程>中第2章对效能分析进行了介绍,基于的工具是VSTS.由于我教授的学生中只有部分同学选修了C#,若采用书中例子讲解,学生可能理解起来比较困难.不过所有这些学生都学习 ...

  7. Apollo配置中心源码分析

    Apollo配置中心源码分析 1. apollo的核心代码分享 SpringApplication启动的关键步骤 在SpringApplication中,会加载所有实现了Init方法的类 protec ...

  8. HanLP中人名识别分析

    HanLP中人名识别分析 在看源码之前,先看几遍论文<基于角色标注的中国人名自动识别研究> 关于命名识别的一些问题,可参考下列一些issue: 名字识别的问题 #387 机构名识别错误 关 ...

  9. linux内核中链表代码分析---list.h头文件分析(一)【转】

    转自:http://blog.chinaunix.net/uid-30254565-id-5637596.html linux内核中链表代码分析---list.h头文件分析(一) 16年2月27日17 ...

随机推荐

  1. QJson 的使用

    下载 源码解压 https://github.com/flavio/qjson 复制 src 目录下所有 .h .cpp .hh 文件到项目目录 qjson,pro 文件添加 INCLUDEPATH ...

  2. Windows下Vundle安装

    鼠标手老是发作,没办法.想学习vim尽量减少编码时使用鼠标的频率.安装好gVim开始安装Vundle插件,总结下安装过程和各种遇到的坑: github上VundleVim倒是有说明 Windows S ...

  3. Java之定时任务详解

    在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现.下面就其原理.实例以及Timer缺陷三个方面来解析java Timer定时器. 在 ...

  4. js 常用正则表达式(不断维护中)

    身份证:pattern="/^[1-9]{1}[0-9]{14}$|^[1-9]{1}[0-9]{16}([0-9]|[xX])$/"

  5. Font Awesome 4.0.3 字体图标完美兼容IE7

    1.下载Font Awesome 4.0.3兼容包,http://www.thinkcmf.com/index.php?m=font 2.解压,并放到自己网站系统合适的位置(如果你的站已使用Font ...

  6. 自定义filter

    class md5_filter extends php_user_filter{ public function filter($in,$out,&$consumed,$closing){ ...

  7. STL初步

    1.stackstack 模板类的定义在<stack>头文件中.stack 模板类需要两个模板参数,一个是元素类型,一个容器类型,但只有元素类型是必要的,在不指定容器类型时,默认的容器类型 ...

  8. Python学习 常识+基础基础

    特点: 优雅,明确,简单 领域: web网站   网络服务   系统工具和脚本 跨平台 对缩进要求严格 注释:# 动态语言:变量本身类型不固定 raw字符串与 多行字符串 raw字符串: 不需要转义字 ...

  9. ModelMap和ModelAndView(转)

    转自:http://bao1073740756-126-com.iteye.com/blog/1549597 首先介绍ModelMap和ModelAndView的作用 ModelMap ModelMa ...

  10. 浅谈38K红外发射接受编码

    之前做接触过一次红外遥控器,现在有空想用简单的话来聊一聊,下面有错误的地方欢迎改正指出:1:红外的概念不聊,那是一种物理存在.以下聊38K红外发射接收,主要讲可编程的红外编码.2:红外遥控 红外遥控首 ...