提供了对引用计数对象的管理,其实也就是操作引用计数对象,当引用计数为零的时候将对象销毁,值得学习的是juce是如果将引用计数对象和它的智能指针结合在一起的,这个后面再加分析
//============================================================================== /** A smart-pointer class which points to a reference-counted object. The template parameter specifies the class of the object you want to point to - the easiest way to make a class reference-countable is to simply make it inherit from ReferenceCountedObject or SingleThreadedReferenceCountedObject, but if you need to, you can roll your own reference-countable class by implementing a set of methods called incReferenceCount(), decReferenceCount(), and decReferenceCountWithoutDeleting(). See ReferenceCountedObject for examples of how these methods should behave. When using this class, you‘ll probably want to create a typedef to abbreviate the full templated name - e.g. @code struct MyClass : public ReferenceCountedObject { typedef ReferenceCountedObjectPtr<MyClass> Ptr; ... @endcode @see ReferenceCountedObject, ReferenceCountedObjectArray */ template <class ReferenceCountedObjectClass> class ReferenceCountedObjectPtr { public: /** The class being referenced by this pointer. */ typedef ReferenceCountedObjectClass ReferencedType; //============================================================================== /** Creates a pointer to a null object. */ ReferenceCountedObjectPtr() noexcept : referencedObject (nullptr) { } /** Creates a pointer to an object. This will increment the object‘s reference-count. */ ReferenceCountedObjectPtr (ReferencedType* refCountedObject) noexcept : referencedObject (refCountedObject) { incIfNotNull (refCountedObject); } /** Copies another pointer. This will increment the object‘s reference-count. */ ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr& other) noexcept : referencedObject (other.referencedObject) { incIfNotNull (referencedObject); } /** Copies another pointer. This will increment the object‘s reference-count (if it is non-null). */ template <class Convertible> ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr<Convertible>& other) noexcept : referencedObject (static_cast<ReferencedType*> (other.get())) { incIfNotNull (referencedObject); } /** Changes this pointer to point at a different object. The reference count of the old object is decremented, and it might be deleted if it hits zero. The new object‘s count is incremented. */ ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr& other) { return operator= (other.referencedObject); } /** Changes this pointer to point at a different object. The reference count of the old object is decremented, and it might be deleted if it hits zero. The new object‘s count is incremented. */ template <class Convertible> ReferenceCountedObjectPtr& operator= (const ReferenceCountedObjectPtr<Convertible>& other) { return operator= (static_cast<ReferencedType*> (other.get())); } /** Changes this pointer to point at a different object. The reference count of the old object is decremented, and it might be deleted if it hits zero. The new object‘s count is incremented. */ ReferenceCountedObjectPtr& operator= (ReferencedType* const newObject) { if (referencedObject != newObject) { incIfNotNull (newObject); ReferencedType* const oldObject = referencedObject; referencedObject = newObject; decIfNotNull (oldObject); } return *this; } #if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS /** Takes-over the object from another pointer. */ ReferenceCountedObjectPtr (ReferenceCountedObjectPtr&& other) noexcept : referencedObject (other.referencedObject) { other.referencedObject = nullptr; } /** Takes-over the object from another pointer. */ ReferenceCountedObjectPtr& operator= (ReferenceCountedObjectPtr&& other) { std::swap (referencedObject, other.referencedObject); return *this; } #endif /** Destructor. This will decrement the object‘s reference-count, which will cause the object to be deleted when the ref-count hits zero. */ ~ReferenceCountedObjectPtr() { decIfNotNull (referencedObject); } //============================================================================== /** Returns the object that this pointer references. The pointer returned may be null, of course. */ operator ReferencedType*() const noexcept { return referencedObject; } /** Returns the object that this pointer references. The pointer returned may be null, of course. */ ReferencedType* get() const noexcept { return referencedObject; } /** Returns the object that this pointer references. The pointer returned may be null, of course. */ ReferencedType* getObject() const noexcept { return referencedObject; } // the -> operator is called on the referenced object ReferencedType* operator->() const noexcept { jassert (referencedObject != nullptr); // null pointer method call! return referencedObject; } private: //============================================================================== ReferencedType* referencedObject; static void incIfNotNull (ReferencedType* o) noexcept { if (o != nullptr) o->incReferenceCount(); } static void decIfNotNull (ReferencedType* o) noexcept { if (o != nullptr && o->decReferenceCountWithoutDeleting()) ContainerDeletePolicy<ReferencedType>::destroy (o); } }; //============================================================================== /** Compares two ReferenceCountedObjectPtrs. */ template <class ReferenceCountedObjectClass> bool operator== (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object1, ReferenceCountedObjectClass* const object2) noexcept { return object1.get() == object2; } /** Compares two ReferenceCountedObjectPtrs. */ template <class ReferenceCountedObjectClass> bool operator== (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object1, const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object2) noexcept { return object1.get() == object2.get(); } /** Compares two ReferenceCountedObjectPtrs. */ template <class ReferenceCountedObjectClass> bool operator== (ReferenceCountedObjectClass* object1, const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object2) noexcept { return object1 == object2.get(); } /** Compares two ReferenceCountedObjectPtrs. */ template <class ReferenceCountedObjectClass> bool operator!= (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object1, const ReferenceCountedObjectClass* object2) noexcept { return object1.get() != object2; } /** Compares two ReferenceCountedObjectPtrs. */ template <class ReferenceCountedObjectClass> bool operator!= (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object1, const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object2) noexcept { return object1.get() != object2.get(); } /** Compares two ReferenceCountedObjectPtrs. */ template <class ReferenceCountedObjectClass> bool operator!= (ReferenceCountedObjectClass* object1, const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& object2) noexcept { return object1 != object2.get(); } #endif // JUCE_REFERENCECOUNTEDOBJECT_H_INCLUDED
值得注意的是对象转移的时候,同样是增加新对象的引用计数,减去原有对象的引用计数
/** Changes this pointer to point at a different object. The reference count of the old object is decremented, and it might be deleted if it hits zero. The new object‘s count is incremented. */ ReferenceCountedObjectPtr& operator= (ReferencedType* const newObject) { if (referencedObject != newObject) { incIfNotNull (newObject); ReferencedType* const oldObject = referencedObject; referencedObject = newObject; decIfNotNull (oldObject); } return *this; }
时间: 2024-10-27 09:28:30