/* -*- C++ -*- */ //============================================================================= /** * @file Bound_Ptr.h * * $Id$ * * @author Christopher Kohlhoff */ //============================================================================= #ifndef ACE_BOUND_PTR_H #define ACE_BOUND_PTR_H #include "ace/pre.h" #include "ace/OS.h" #include "ace/Auto_Ptr.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ /** * @class ACE_Bound_Ptr_Counter * * @brief An ACE_Bound_Ptr_Counter object encapsulates an object * reference count. Do not use this class directly, use ACE_Strong_Bound_Ptr * or ACE_Weak_Bound_Ptr instead. */ template class ACE_Bound_Ptr_Counter { public: /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; ACE_Bound_Ptr_Counter (int init_obj_ref_count = 0); ~ACE_Bound_Ptr_Counter (void); /// Create a ACE_Bound_Ptr_Counter and initialize the reference /// count to indicate ownership by a strong pointer. static ACE_Bound_Ptr_Counter *create_strong (void); /// Increase both the object and counter reference counts and return the new /// object reference count. A return value of -1 indicates that the object /// has already been destroyed. static int attach_strong (ACE_Bound_Ptr_Counter *counter); /// Decreases both the object and counter reference counts and deletes /// whichever has no more references. Returns the new object reference count. static int detach_strong (ACE_Bound_Ptr_Counter *counter); /// Create a ACE_Bound_Ptr_Counter and initialize the reference /// count to indicate no ownership. static ACE_Bound_Ptr_Counter *create_weak (void); /// Increase the counter reference count and return argument. static void attach_weak (ACE_Bound_Ptr_Counter *counter); /// Decreases the counter reference count and deletes the counter if it has /// no more references. static void detach_weak (ACE_Bound_Ptr_Counter *counter); /// Determine whether the object has been deleted. static int object_was_deleted (ACE_Bound_Ptr_Counter *counter); private: /// Allocate a new ACE_Bound_Ptr_Counter instance, returning NULL /// if it cannot be created. static ACE_Bound_Ptr_Counter *internal_create (int init_obj_ref_count); /// Reference count of underlying object. Is set to -1 once the object has /// been destroyed to indicate to all weak pointers that it is no longer valid. int obj_ref_count_; /// Reference count of this counter. int self_ref_count_; /// Mutex variable to synchronize access to the reference counts. ACE_LOCK lock_; }; // Forward decl. template class ACE_Weak_Bound_Ptr; /** * @class ACE_Strong_Bound_Ptr * * @brief This class implements support for a reference counted pointer. * Assigning or copying instances of an ACE_Strong_Bound_Ptr will * automatically increment the reference count of the underlying object. * When the last instance of an ACE_Strong_Bound_Ptr that references a * particular object is destroyed or overwritten, it will invoke delete * on its underlying pointer. */ template class ACE_Strong_Bound_Ptr { public: /// Constructor that initializes an ACE_Strong_Bound_Ptr to point to the /// object

immediately. ACE_EXPLICIT ACE_Strong_Bound_Ptr (X *p = 0); /// Constructor that initializes an ACE_Strong_Bound_Ptr by stealing /// ownership of an object from an auto_ptr. ACE_EXPLICIT ACE_Strong_Bound_Ptr (auto_ptr p); /// Copy constructor binds and to the same object. ACE_Strong_Bound_Ptr (const ACE_Strong_Bound_Ptr &r); /// Constructor binds and to the same object. ACE_Strong_Bound_Ptr (const ACE_Weak_Bound_Ptr &r); /// Destructor. ~ACE_Strong_Bound_Ptr (void); /// Assignment operator that binds and to the same object. void operator = (const ACE_Strong_Bound_Ptr &r); /// Assignment operator that binds and to the same object. void operator = (const ACE_Weak_Bound_Ptr &r); /// Equality operator that returns 1 if both ACE_Strong_Bound_Ptr instances /// point to the same underlying object. Attention: It also returns 1 if /// both objects have just been instantiated and not used yet. int operator == (const ACE_Strong_Bound_Ptr &r) const; /// Equality operator that returns 1 if the ACE_Strong_Bound_Ptr and /// ACE_Weak_Bound_Ptr objects point to the same underlying object. /// Attention: It also returns 1 if both objects have just been /// instantiated and not used yet. int operator == (const ACE_Weak_Bound_Ptr &r) const; /// Equality operator that returns 1 if the ACE_Strong_Bound_Ptr and the raw /// pointer point to the same underlying object. int operator == (X *p) const; /// Inequality operator, which is the opposite of equality. int operator != (const ACE_Strong_Bound_Ptr &r) const; /// Inequality operator, which is the opposite of equality. int operator != (const ACE_Weak_Bound_Ptr &r) const; /// Inequality operator, which is the opposite of equality. int operator != (X *p) const; /// Redirection operator X *operator-> (void) const; /// Dereference operator X &operator * (void) const; /// Get the pointer value. X *get (void); /// Resets the ACE_Strong_Bound_Ptr to refer to a different underlying /// object. void reset (X *p = 0); /// Resets the ACE_Strong_Bound_Ptr to refer to a different underlying /// object, ownership of which is stolen from the auto_ptr. void reset (auto_ptr p); /// Allows us to check for NULL on all ACE_Strong_Bound_Ptr objects. int null (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; private: friend class ACE_Weak_Bound_Ptr; /// The ACE_Bound_Ptr_Counter type. typedef ACE_Bound_Ptr_Counter COUNTER; /// The reference counter. COUNTER *counter_; /// The underlying object. X *ptr_; }; /** * @class ACE_Weak_Bound_Ptr * * @brief This class implements support for a weak pointer that complements * ACE_Strong_Bound_Ptr. Unlike ACE_Strong_Bound_Ptr, assigning or copying * instances of an ACE_Weak_Bound_Ptr will not automatically increment the * reference count of the underlying object. What ACE_Weak_Bound_Ptr does is * preserve the knowledge that the object is in fact reference counted, and * thus provides an alternative to raw pointers where non-ownership * associations must be maintained. When the last instance of an * ACE_Strong_Bound_Ptr that references a particular object is destroyed or * overwritten, the corresponding ACE_Weak_Bound_Ptr instances are set to * null. */ template class ACE_Weak_Bound_Ptr { public: /// Constructor that initializes an ACE_Weak_Bound_Ptr to point to the /// object

immediately. ACE_EXPLICIT ACE_Weak_Bound_Ptr (X *p = 0); /// Copy constructor binds and to the same object. ACE_Weak_Bound_Ptr (const ACE_Weak_Bound_Ptr &r); /// Constructor binds and to the same object. ACE_Weak_Bound_Ptr (const ACE_Strong_Bound_Ptr &r); /// Destructor. ~ACE_Weak_Bound_Ptr (void); /// Assignment operator that binds and to the same object. void operator = (const ACE_Weak_Bound_Ptr &r); /// Assignment operator that binds and to the same object. void operator = (const ACE_Strong_Bound_Ptr &r); /// Equality operator that returns 1 if both ACE_Weak_Bound_Ptr objects /// point to the same underlying object. Attention: It also returns 1 if /// both objects have just been instantiated and not used yet. int operator == (const ACE_Weak_Bound_Ptr &r) const; /// Equality operator that returns 1 if the ACE_Weak_Bound_Ptr and /// ACE_Strong_Bound_Ptr objects point to the same underlying object. /// Attention: It also returns 1 if both objects have just been instantiated /// and not used yet. int operator == (const ACE_Strong_Bound_Ptr &r) const; /// Equality operator that returns 1 if the ACE_Weak_Bound_Ptr and the raw /// pointer point to the same underlying object. int operator == (X *p) const; /// Inequality operator, which is the opposite of equality. int operator != (const ACE_Weak_Bound_Ptr &r) const; /// Inequality operator, which is the opposite of equality. int operator != (const ACE_Strong_Bound_Ptr &r) const; /// Inequality operator, which is the opposite of equality. int operator != (X *p) const; /// Redirection operator. It returns a temporary strong pointer and makes /// use of the chaining properties of operator-> to ensure that the /// underlying object does not disappear while you are using it. If /// you are certain of the lifetimes of the object, and do not want to incur /// the locking overhead, then use the unsafe_get method instead. ACE_Strong_Bound_Ptr operator-> (void) const; /// Obtain a strong pointer corresponding to this weak pointer. This function /// is useful to create a temporary strong pointer for conversion to a /// reference. ACE_Strong_Bound_Ptr strong (void) const; /// Get the pointer value. Warning: this does not affect the reference count /// of the underlying object, so it may disappear on you while you are using /// it if you are not careful. X *unsafe_get (void) const; /// Resets the ACE_Weak_Bound_Ptr to refer to a different underlying object. void reset (X *p = 0); /// Increment the reference count on the underlying object. Returns the new /// reference count on the object. This function may be used to integrate the /// bound pointers into an external reference counting mechanism such as /// those used by COM or CORBA servants. int add_ref (void); /// Decrement the reference count on the underlying object, which is deleted /// if the count has reached zero. Returns the new reference count on the /// object. This function may be used to integrate the bound pointers into an /// external reference counting mechanism such as those used by COM or CORBA /// servants. int remove_ref (void); /// Allows us to check for NULL on all ACE_Weak_Bound_Ptr objects. int null (void) const; /// Declare the dynamic allocation hooks. ACE_ALLOC_HOOK_DECLARE; private: friend class ACE_Strong_Bound_Ptr; /// The ACE_Bound_Ptr_Counter type. typedef ACE_Bound_Ptr_Counter COUNTER; /// The reference counter. COUNTER *counter_; /// The underlying object. X *ptr_; }; #include "ace/Bound_Ptr.i" #include "ace/post.h" #endif /* ACE_BOUND_PTR_H */