00001 #ifndef OBT_GUARDED_POINTER_H 00002 #define OBT_GUARDED_POINTER_H 00003 00004 #include <list> 00005 #include "OBT_ASSERT.h" 00006 00007 namespace OBT 00008 { 00009 class GuardedPointer ; 00010 00017 class PointedObject 00018 { 00019 public: 00021 virtual ~PointedObject() ; 00023 void addPointer( GuardedPointer* p ) { _toUpdate.push_back( p ) ; } 00025 void removePointer( GuardedPointer* p ) { _toUpdate.remove( p ) ; } 00026 private: 00028 std::list< GuardedPointer* > _toUpdate ; 00029 } ; 00036 class GuardedPointer 00037 { 00038 protected: 00040 GuardedPointer() : _callerObject( 0 ) {} 00042 virtual ~GuardedPointer() { _callerObject->removePointer( this ) ; } 00044 PointedObject* _callerObject ; 00045 friend class PointedObject ; 00047 virtual void resetPointedObject() { _callerObject = 0 ; } ; 00048 } ; 00079 template< class T > 00080 class GuardedPointerT : public GuardedPointer 00081 { 00082 public: 00084 GuardedPointerT() : GuardedPointer(), _object( 0 ) { setPointedObject( 0 ) ; } 00086 GuardedPointerT( T* o ) : GuardedPointer(), _object( 0 ) { setPointedObject( o ) ; } 00088 GuardedPointerT( const GuardedPointerT< T >& p ) : GuardedPointer(), _object( 0 ) { setPointedObject( p._object ) ; } 00089 // Destructor. 00090 virtual ~GuardedPointerT() {} 00091 00093 00094 00095 GuardedPointerT< T >& operator = ( T *o ) { setPointedObject( o ) ; return *this ; } 00097 GuardedPointerT< T >& operator = ( const GuardedPointerT< T > &p ) { setPointedObject( p._object ) ; return *this ; } 00099 00101 00102 00103 bool operator == ( T* p ) const { return _object == p ; } 00105 bool operator != ( T* p ) const { return !( *this == p ) ; } 00107 00109 bool isNull() const { return !_object ; } 00110 00111 00113 00114 00115 T* operator->() const { return _object ; } 00117 T& operator*() const { return *_object ; } 00119 operator T*() const { return _object ; } 00120 private: 00122 T* _object ; 00124 virtual void resetPointedObject() { GuardedPointer::resetPointedObject() ; _object = 0 ; } ; 00126 void setPointedObject( T* o ) 00127 { 00128 if( _object != o ) 00129 { 00130 // Remove the pointer from the previous object 00131 if( _callerObject ) _callerObject->removePointer( this ) ; 00132 // Set the object 00133 _callerObject = o ; 00134 _object = o ; 00135 // Add the pointer to the object 00136 if( _callerObject ) _callerObject->addPointer( this ) ; 00137 } 00138 } 00139 }; 00140 00141 } // namespace OBT 00142 00143 // The destructor of the pointed object warns all the pointers 00144 OBT::PointedObject::~PointedObject() 00145 { 00146 // Reset all the pointers 00147 for( std::list< OBT::GuardedPointer* >::iterator i = _toUpdate.begin() ; 00148 i != _toUpdate.end() ; 00149 i ++ ) 00150 (*i)->resetPointedObject() ; 00151 } 00152 00153 #endif // OBT_GUARDED_POINTER_H