gdcmObject.h

Go to the documentation of this file.
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 

Generated on Sat Dec 4 2010 08:58:44 for GDCM by doxygen 1.7.2
SourceForge.net Logo