1 /*========================================================================= 2 3 Program: GDCM (Grassroots DICOM). A DICOM library 4 5 Copyright (c) 2006-2011 Mathieu Malaterre 6 All rights reserved. 7 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. 8 9 This software is distributed WITHOUT ANY WARRANTY; without even 10 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 11 PURPOSE. See the above copyright notice for more information. 12 13 =========================================================================*/ 14 #ifndef GDCMSMARTPOINTER_H 15 #define GDCMSMARTPOINTER_H 16 17 #include "gdcmObject.h" 18 19 namespace gdcm 20 { 21 /** 22 * \brief Class for Smart Pointer 23 * \details 24 * Will only work for subclass of gdcm::Object 25 * See tr1/shared_ptr for a more general approach (not invasive) 26 * #include <tr1/memory> 27 * { 28 * shared_ptr<Bla> b(new Bla); 29 * } 30 * \note 31 * Class partly based on post by Bill Hubauer: 32 * http://groups.google.com/group/comp.lang.c++/msg/173ddc38a827a930 33 * \see 34 * http://www.davethehat.com/articles/smartp.htm 35 * 36 * and itk::SmartPointer 37 */ 38 template<class ObjectType> 39 class SmartPointer 40 { 41 public: SmartPointer()42 SmartPointer():Pointer(nullptr) {} SmartPointer(const SmartPointer<ObjectType> & p)43 SmartPointer(const SmartPointer<ObjectType>& p):Pointer(p.Pointer) 44 { Register(); } SmartPointer(ObjectType * p)45 SmartPointer(ObjectType* p):Pointer(p) 46 { Register(); } SmartPointer(ObjectType const & p)47 SmartPointer(ObjectType const & p) 48 { 49 Pointer = const_cast<ObjectType*>(&p); 50 Register(); 51 } ~SmartPointer()52 ~SmartPointer() { 53 UnRegister(); 54 Pointer = nullptr; 55 } 56 57 /// Overload operator -> 58 ObjectType *operator -> () const 59 { return Pointer; } 60 61 ObjectType& operator * () const 62 { 63 assert( Pointer ); 64 return *Pointer; 65 } 66 67 /// Return pointer to object. 68 operator ObjectType * () const 69 { return Pointer; } 70 71 /// Overload operator assignment. 72 SmartPointer &operator = (SmartPointer const &r) 73 { return operator = (r.Pointer); } 74 75 /// Overload operator assignment. 76 SmartPointer &operator = (ObjectType *r) 77 { 78 // http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.22 79 // DO NOT CHANGE THE ORDER OF THESE STATEMENTS! 80 // (This order properly handles self-assignment) 81 // (This order also properly handles recursion, e.g., if a ObjectType contains SmartPointer<ObjectType>s) 82 if( Pointer != r ) 83 { 84 ObjectType* old = Pointer; 85 Pointer = r; 86 Register(); 87 if ( old ) { old->UnRegister(); } 88 } 89 return *this; 90 } 91 92 SmartPointer &operator = (ObjectType const &r) 93 { 94 ObjectType* tmp = const_cast<ObjectType*>(&r); 95 return operator = (tmp); 96 } 97 98 /// Explicit function to retrieve the pointer GetPointer()99 ObjectType *GetPointer() const 100 { return Pointer; } 101 102 private: Register()103 void Register() 104 { 105 if(Pointer) Pointer->Register(); 106 } 107 UnRegister()108 void UnRegister() 109 { 110 if(Pointer) Pointer->UnRegister(); 111 } 112 113 ObjectType* Pointer; 114 }; 115 116 } // end namespace gdcm 117 118 #endif //GDCMSMARTPOINTER_H 119