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