// -*- C++ -*- //========================================================================== /** * @file Value_Ptr.h * * Value_Ptr implementation based on code in Herb Sutter's book "More * Exceptional C++". * * @author Ossama Othman */ //========================================================================== #ifndef ACE_VALUE_PTR_H #define ACE_VALUE_PTR_H #include /**/ "ace/config-lite.h" #include ACE_BEGIN_VERSIONED_NAMESPACE_DECL namespace ACE { /** * @struct VP_traits * * @brief @c Value_Ptr traits template structure. * * The @c Value_Ptr template class delegates some operations to this * template traits structure. * * Specialize this trait template if cloning through copy * construction is not sufficient. For example, to avoid slicing * when copying an object through a base class pointer, one can * implement a virtual "clone" method that can be used to * polymorphically invoke the appropriate cloning operation(s). * That virtual method would then be invoked by the @c VP_traits\<\> * specialization. */ template struct VP_traits { /// Copy the given object. static T * clone (T const * p) { return new T (*p); } }; /** * @class Value_Ptr * * @brief Smart pointer implementation designed for use as a class * member. * * Using a @c std::auto_ptr\<\> as a class member is sometimes * problematic since ownership of memory is transferred when copying * such members. This @c Value_Ptr class is explicitly designed to * avoid such problems by performing copies of the underlying object * rather than transfer ownership. This, for example, allows it to * be readily used as a member in classes placed inside STL * containers. * * @see Item 31 in "More Exceptional C++" by Herb Sutter. */ template class Value_Ptr { public: /// Constructor. explicit Value_Ptr (T * p = 0) : p_ (p) {} /// Destructor. ~Value_Ptr () { delete this->p_; } /// Deference operator. T & operator* () const { return *this->p_; } /// Pointer operator. T * operator-> () const { return this->p_; } /// Non-throwing swap operation used to make assignment strongly /// exception-safe. /** * @note As implemented, the swap operation may not work correctly * for @c auto_ptr\<\>s, but why would one use an @c * auto_ptr\<\> as the template argument for this particular * template class!? */ void swap (Value_Ptr & other) { std::swap (this->p_, other.p_); } /// Copy constructor. Value_Ptr (Value_Ptr const & other) : p_ (create_from (other.p_)) { } /// Assignment operator. Value_Ptr & operator= (Value_Ptr const & other) { // Strongly exception-safe. Value_Ptr temp (other); this->swap (temp); return *this; } /// Converting copy constructor. template Value_Ptr (Value_Ptr const & other) : p_ (create_from (other.p_)) { } /// Converting assignment operator. template Value_Ptr & operator= (Value_Ptr const & other) { // Strongly exception-safe. Value_Ptr temp (other); this->swap (temp); return *this; } private: /// Copying method invoked when copy constructing. template T * create_from (U const * p) const { return p ? VP_traits::clone (p) : 0; } private: template friend class Value_Ptr; /// Object owned by this @c Value_Ptr. T * p_; }; } ACE_END_VERSIONED_NAMESPACE_DECL #endif /* ACE_VALUE_PTR_H */