00001 /*========================================================================= 00002 00003 Program: GDCM (Grassroots DICOM). A DICOM library 00004 Module: $URL$ 00005 00006 Copyright (c) 2006-2010 Mathieu Malaterre 00007 All rights reserved. 00008 See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details. 00009 00010 This software is distributed WITHOUT ANY WARRANTY; without even 00011 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00012 PURPOSE. See the above copyright notice for more information. 00013 00014 =========================================================================*/ 00015 #ifndef GDCMOBJECT_H 00016 #define GDCMOBJECT_H 00017 00018 #include "gdcmTypes.h" 00019 00020 #include <assert.h> 00021 #include <iostream> // grrrr 00022 00023 //namespace std { class ostream; } 00024 namespace gdcm 00025 { 00026 00027 template<class ObjectType> class SmartPointer; 00028 00037 class GDCM_EXPORT Object 00038 { 00039 template <class ObjectType> friend class SmartPointer; 00040 friend std::ostream& operator<<(std::ostream &os, const Object &obj); 00041 00042 public: 00043 Object():ReferenceCount(0) {} 00044 00045 // Implementation note: 00046 // If I move ~Object in the protected section I can prevent people 00047 // from writing: 00048 // SmartPointer<Object> p = new Object; 00049 // delete p; // due to SmartPointer::operator ObjectType * () const 00050 // but on the other hand one could not define an Object on the stack 00051 // Object obj; 00052 // Furthermore it would not prevent anyone from doing: 00053 // class MyObject : public Object {}; 00054 // SmartPointer<MyObject> o = new MyObject; 00055 // delete o; // grrrrrr 00056 virtual ~Object() { 00057 // If your debugger reach here it means you are doing something silly 00058 // like using SmartPointer on object allocated on the stack (vs heap) 00059 assert(ReferenceCount == 0); 00060 } 00061 00062 // http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.24 00063 // Set the ref count to 0 00064 // Do NOT copy the reference count ! 00066 Object(const Object&):ReferenceCount(0){} 00067 void operator=(const Object&){} 00068 00069 //static Object* New() { return new Object; } 00070 00071 protected: 00072 // For the purpose of the invasive SmartPointer implementation 00073 void Register() { 00074 ReferenceCount++; 00075 assert( ReferenceCount > 0 ); 00076 } 00077 void UnRegister() { 00078 assert( ReferenceCount > 0 ); 00079 ReferenceCount--; 00080 if(!ReferenceCount) 00081 { 00082 delete this; 00083 } 00084 } 00085 00086 public: 00087 // For dealing with printing of object and polymorphism 00088 virtual void Print(std::ostream &) const {} 00089 00090 private: 00091 long ReferenceCount; 00092 }; 00093 00094 //---------------------------------------------------------------------------- 00095 // function do not carry vtable. Thus define in the base class the operator 00096 // and use the member function ->Print() to call the appropriate function 00097 // NOTE: All subclass of Object needs to implement the Print function 00098 inline std::ostream& operator<<(std::ostream &os, const Object &obj) 00099 { 00100 obj.Print(os); 00101 return os; 00102 } 00103 00104 } // end namespace gdcm 00105 00106 #endif //GDCMOBJECT_H 00107