Juce源码分析(七)弱引用(2)引用对象指针的维护与原对象析构后的通知

来源:互联网 发布:金融投资源码 编辑:程序博客网 时间:2024/04/30 08:02

弱引用的使用方法如下

  class MyObject    {    public:        MyObject()        {            // If you're planning on using your WeakReferences in a multi-threaded situation, you may choose            // to create a WeakReference to the object here in the constructor, which will pre-initialise the            // embedded object, avoiding an (extremely unlikely) race condition that could occur if multiple            // threads overlap while creating the first WeakReference to it.        }        ~MyObject()        {            // This will zero all the references - you need to call this in your destructor.            masterReference.clear();        }    private:        // You need to embed a variable of this type, with the name "masterReference" inside your object. If the        // variable is not public, you should make your class a friend of WeakReference<MyObject> so that the        // WeakReference class can access it.        WeakReference<MyObject>::Master masterReference;        friend class WeakReference<MyObject>;    };    MyObject* n = new MyObject();    WeakReference<MyObject> myObjectRef = n;    MyObject* pointer1 = myObjectRef;  // returns a valid pointer to 'n'    delete n;    MyObject* pointer2 = myObjectRef;  // returns a null pointer


       那么,当delete n时,myObjectRef是如何发生改变的呢?不难猜到,肯定是在MyObject的析构函数里做了处理。每一个类在使用弱引用是都需要添加一个    WeakReference<MyObject>::Master masterReference;的属性(注意,对象的名字都不能改,必须是masterReference),当对象被delete的时候,masterReference通知WeakReference导致引用失效,将指针指针赋值为空指针,其实原理就这么简单,复杂的地方在于弱引用的生命周期的管理,引用对象的创建,复制,传递,析构,不过把这项工作交给上次说到的ReferenceCountedObjectPtr来管理,就没有那么复杂了,ReferenceCountedObjectPtr采用引用计数原理,来控制所指向对象的生命周期,功能相当于shared_ptr。把这两点弄明白,Juce的弱引用遍不再神秘,第一,原对象析构时的通知,因为弱引用是要代替原对象的指针使用,所以引用对象里面维护的是原对象的裸指针,当对象析构时,析构函数将引用对象里的原对象指针赋值为空指针,弱引用的目的便达到了;第二,引用对象生命周期的智能管理,因为引用对象也是使用new关键字在堆中创建的对象,引用对象也存在指针,为了使引用对象智能管理,所以又使用ReferenceCountedObjectPtr来维护引用对象的生命周期,使引用对象也做到智能化管理。整体来说,弱引用相对于原对象来说,是封装了两层,相当于原对象的指针的指针,这两层的实现就是为了达到以上两点的目的。


     下面贴出带有关键注释的源码:

/*第二层,SharedPointer对象的智能管理,SharedPointer对象的智能指针*/template <class ObjectType, class ReferenceCountingType = ReferenceCountedObject>class WeakReference{public:    /** Creates a null SafePointer. */    inline WeakReference() noexcept {}    /** Creates a WeakReference that points at the given object. */    WeakReference (ObjectType* const object)  : holder (getRef (object)) {}    /** Creates a copy of another WeakReference. */    WeakReference (const WeakReference& other) noexcept         : holder (other.holder) {}    /** Copies another pointer to this one. */    WeakReference& operator= (const WeakReference& other)       { holder = other.holder; return *this; }    /** Copies another pointer to this one. */    WeakReference& operator= (ObjectType* const newObject)      { holder = getRef (newObject); return *this; }   #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS    WeakReference (WeakReference&& other) noexcept              : holder (static_cast <SharedRef&&> (other.holder)) {}    WeakReference& operator= (WeakReference&& other) noexcept   { holder = static_cast <SharedRef&&> (other.holder); return *this; }   #endif    /** Returns the object that this pointer refers to, or null if the object no longer exists. */    ObjectType* get() const noexcept                            { return holder != nullptr ? holder->get() : nullptr; }    /** Returns the object that this pointer refers to, or null if the object no longer exists. */    operator ObjectType*() const noexcept                       { return get(); }    /** Returns the object that this pointer refers to, or null if the object no longer exists. */    ObjectType* operator->() noexcept                           { return get(); }    /** Returns the object that this pointer refers to, or null if the object no longer exists. */    const ObjectType* operator->() const noexcept               { return get(); }    /** This returns true if this reference has been pointing at an object, but that object has        since been deleted.        If this reference was only ever pointing at a null pointer, this will return false. Using        operator=() to make this refer to a different object will reset this flag to match the status        of the reference from which you're copying.    */    bool wasObjectDeleted() const noexcept                      { return holder != nullptr && holder->get() == nullptr; }    bool operator== (ObjectType* const object) const noexcept   { return get() == object; }    bool operator!= (ObjectType* const object) const noexcept   { return get() != object; }    //==============================================================================    /** This class is used internally by the WeakReference class - don't use it directly        in your code!        @see WeakReference第一层,引用对象,通过Master对象调用clearPointer(),将原对象指针赋值为nullptr    */    class SharedPointer   : public ReferenceCountingType       {    public:        explicit SharedPointer (ObjectType* const obj) noexcept : owner (obj) {}        inline ObjectType* get() const noexcept     { return owner; }        void clearPointer() noexcept                { owner = nullptr; }    private:        ObjectType* volatile owner;        JUCE_DECLARE_NON_COPYABLE (SharedPointer)    };    typedef ReferenceCountedObjectPtr<SharedPointer> SharedRef;    //==============================================================================    /**        This class is embedded inside an object to which you want to attach WeakReference pointers.        See the WeakReference class notes for an example of how to use this class.        @see WeakReference原对象析构时,由原对象中的Master对象成员来通知    */    class Master    {    public:        Master() noexcept {}        ~Master() noexcept        {            // You must remember to call clear() in your source object's destructor! See the notes            // for the WeakReference class for an example of how to do this.            jassert (sharedPointer == nullptr || sharedPointer->get() == nullptr);        }        /** The first call to this method will create an internal object that is shared by all weak            references to the object.        */        SharedPointer* getSharedPointer (ObjectType* const object)        {            if (sharedPointer == nullptr)            {                sharedPointer = new SharedPointer (object);            }            else            {                // You're trying to create a weak reference to an object that has already been deleted!!                jassert (sharedPointer->get() != nullptr);            }            return sharedPointer;        }        /** The object that owns this master pointer should call this before it gets destroyed,            to zero all the references to this object that may be out there. See the WeakReference            class notes for an example of how to do this.        */        void clear() noexcept        {            if (sharedPointer != nullptr)                sharedPointer->clearPointer();        }    private:        SharedRef sharedPointer;        JUCE_DECLARE_NON_COPYABLE (Master)    };private:    SharedRef holder;    static inline SharedPointer* getRef (ObjectType* const o)    {        return (o != nullptr) ? o->masterReference.getSharedPointer (o) : nullptr;    }};

        配合上一节的内容,通过上面的代码,相信大家可以清晰地看到WeakReference的两层的结构,理解这两层结构实现的方式与目的







0 0
原创粉丝点击