📄 ref.h
字号:
if (!managed()) return 1;# endif __REF_LOCK__(this);# if REF_CHECK_MIN_NREF if (_reference_count_ == 0) not_enough_refs();# endif _reference_count_--; refcount_t r = _reference_count_; __REF_UNLOCK__(this); return r; }#if REF_MANAGE int managed() const { return _reference_count_ != REF_MANAGED_CODE; } /** Turn off the reference counting mechanism for this object. The value returned by nreference() will always be 1 after this is called. The ability to unmanage() objects must be turned on at compile time by defining REF_MANAGE. There is a slight performance penalty. */ void unmanage() { _reference_count_ = REF_MANAGED_CODE; }#else // REF_MANAGE /// Return 1 if the object is managed. Otherwise return 0. int managed() const { return 1; }#endif // REF_MANAGE};/** Provides a few utility routines common to all Ref template instantiations.*/class RefBase { protected: /// Print a warning message. void warn ( const char * msg) const; /// Called when stack data is referenced. void warn_ref_to_stack() const; /// Called when the deletion of stack data is skipped. void warn_skip_stack_delete() const; /// Called when the reference count is corrupted. void warn_bad_ref_count() const; /// Print information about the reference. void ref_info(RefCount*p,std::ostream& os) const; void ref_info(std::ostream& os) const; void check_pointer() const; void reference(RefCount *); int dereference(RefCount *); public: virtual ~RefBase(); /// Returns the DescribedClass pointer for the contained object. virtual RefCount* parentpointer() const = 0; /** Requires that a nonnull reference is held. If not, the program will abort. */ void require_nonnull() const;};/** A template class that maintains references counts. Several of these operations can cause a reference to an object to be replaced by a reference to a different object. If a reference to a nonnull object is eliminated, the object's reference count is decremented and the object is deleted if the reference count becomes zero. There also may be a to convert to T*, where T is the type of the object which Ref references. Some compilers have bugs that prevent the use of operator T*(). The pointer() member should be used instead. */template <class T>class Ref : public RefBase { private: T* p; public: /// Create a reference to a null object. Ref(): p(0) {} /// Create a reference to the object a. Ref(T*a) : p(0) { if (a) { p = a; reference(p); } } /// Create a reference to the object referred to by a. Ref(const Ref<T> &a) : p(0) { if (a.pointer()) { p = a.pointer(); reference(p); } } /// Create a reference to the object referred to by a. template <class A> Ref(const Ref<A> &a): p(0) { if (a.pointer()) { p = a.pointer(); reference(p); } }// /** Create a reference to the object a. Do a// dynamic_cast to convert a to the appropiate type. */// Ref(const RefBase&a) {// p = dynamic_cast<T*>(a.parentpointer());// reference(p);// }// /** Create a reference to the object a. Do a// dynamic_cast to convert a to the appropiate type. */// Ref(RefCount*a): p(0) {// operator<<(a);// } /** Delete this reference to the object. Decrement the object's reference count and delete the object if the count is zero. */ ~Ref() { clear(); } /** Returns the reference counted object. The behaviour is undefined if the object is null. */ T* operator->() const { return p; } /// Returns a pointer the reference counted object. T* pointer() const { return p; } /// Implements the parentpointer pure virtual in the base class. RefCount *parentpointer() const { return p; } operator T*() const { return p; } /** Returns a C++ reference to the reference counted object. The behaviour is undefined if the object is null. */ T& operator *() const { return *p; }; /** Return 1 if this is a reference to a null object. Otherwise return 0. */ int null() const { return p == 0; } /// Return !null(). int nonnull() const { return p != 0; } /** A variety of ordering and equivalence operators are provided using the Identity class. */ template <class A> int operator==(const Ref<A>&a) const { return eq(p,a.pointer()); } template <class A> int operator>=(const Ref<A>&a) const { return ge(p,a.pointer()); } template <class A> int operator<=(const Ref<A>&a) const { return le(p,a.pointer()); } template <class A> int operator>(const Ref<A>&a) const { return gt(p,a.pointer()); } template <class A> int operator<(const Ref<A>&a) const { return lt(p,a.pointer()); } template <class A> int operator!=(const Ref<A>&a) const { return ne(p,a.pointer()); } /** Compare two objects returning -1, 0, or 1. Similar to the C library routine strcmp. */ int compare(const Ref<T> &a) const { return eq(p,a.p)?0:((lt(p,a.p)?-1:1)); } /// Refer to the null object. void clear() { if (p) { int ref = dereference(p); if (ref == 0) delete p; p = 0; } } /// Assignment to c. Ref<T>& operator=(const Ref<T> & c) { T *cp = c.pointer(); if (cp) { cp->reference(); clear(); p=cp; } else { clear(); } return *this; } /// Assignment to c. template <class A> Ref<T>& operator=(const Ref<A> & c) { A *cp = c.pointer(); if (cp) { cp->reference(); clear(); p=cp; } else { clear(); } return *this; } /// Assignment to the object that a references using dynamic_cast. Ref<T>& operator<<(const RefBase&a) { T* cr = dynamic_cast<T*>(a.parentpointer()); if (cr) { reference(cr); clear(); } p = cr; return *this; } /** Assigns to the given base class pointer using dynamic_cast. If the dynamic_cast fails and the argument is nonnull and has a reference count of zero, then it is deleted. */ Ref<T>& operator<<(RefCount *a) { T* cr = dynamic_cast<T*>(a); if (cr) assign_pointer(cr); else if (a && a->nreference() <= 0) delete a; return *this; } /// Assignment to cr. Ref<T>& operator=(T* cr) { assign_pointer(cr); return *this; } /// Assignment to cr. void assign_pointer(T* cr) { if (cr) { if (DO_REF_CHECK_STACK(cr)) { DO_REF_UNMANAGE(cr); warn_ref_to_stack(); } cr->reference(); } clear(); p = cr; } /// Check the validity of the pointer. void check_pointer() const { if (p && p->nreference() <= 0) { warn_bad_ref_count(); } } /// Print information about the reference to os. void ref_info(std::ostream& os) const { RefBase::ref_info(p,os); } /// Print a warning concerning the reference. void warn(const char*s) const { RefBase::warn(s); }};}#endif// ///////////////////////////////////////////////////////////////////////////// Local Variables:// mode: c++// c-file-style: "CLJ"// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -