Re: Destructor for const object
From: Nick Hounsome (nh002_at_blueyonder.co.uk)
Date: 04/14/04
- Previous message: Kevin Goodsell: "Re: ifstream"
- In reply to: Virendra Verma: "Re: Destructor for const object"
- Next in thread: Virendra Verma: "Re: Destructor for const object"
- Reply: Virendra Verma: "Re: Destructor for const object"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 14 Apr 2004 08:28:28 +0100
"Virendra Verma" <virenbeena@hotmail.com> wrote in message
news:30ee7e04.0404131108.1df58d18@posting.google.com...
> Thanks both of you.
>
> I believe I have to use a reference counted class. The problem with
> the above scenario was that I was using class variables for DbPtr
> class which get duplicated before returning and thus committing both
> copies. Here is the code that does the trick. DbBasePtr class is only
> a single copy and keeps track commit status. If the copy is already
> committed, second commit will simply be ignored.
>
It is still not clear what you are trying to do but I believe that it is
still
totally wrong.
1. For the DbAutoPtr you cannot have the reference count in the pointer.
It must either be in the object pointed to or on the heap.
2. DbAutoPtr ctor should take a T* because it is supposed to point to a T.
3. The pointer should ONLY do the owning/commit. Use a separate mechanism to
create new instances or find them initially in the db.
4. The sizeof suggests an extremely dodgy implementation. I suggest that you
should be allocating
these things with a custom new: as in DbAutoPtr<X> xp = new(db) X;
5. Your DbRefCount isn't a reference count. I think I see what you are
trying to do but you can
do this more cleanly by storing the reference count separately - the ref
count should not be
in the DB unless you have multiple concurrent cliemts with locking.
> I have another question. In my DbAutoPtr<T> class below, which
> operator gets called for the rvalue operand, a->? Is there an implicit
> or elegant (without creating or typecasting to a const object) way of
> "const T& operator->( ) const" version to be called as the rvalue is
> not being modified?
1. What's wrong with const T*?
2. -> operates on pointers not references.
>
> struct C {
> int x;
> };
>
> struct A {
> int y;
> };
>
>
> DbStore db;
> DbAutoPtr< C> p(db, 0, sizeof( C ) );
> DbAutoPtr< A > a( db, 0, sizeof(A) );
>
> p->x = a->y;
>
>
> ===================
> // DbAutPtr.h - auto pinter
>
> #ifndef _DBAUTPTR_H_
> #define _DBAUTPTR_H_
>
> #include "syTypes.h"
> #include "DbDefs.h"
> #include "DbBasPtr.h"
> #include "DbRefCnt.h"
>
> class DbStore;
>
> //////////////////////////////////////////////////////////////////////////
> // DbAutoPtr< T > class
> //////////////////////////////////////////////////////////////////////////
> template< class T >
> class DbAutoPtr {
> public:
> DbAutoPtr( );
> DbAutoPtr( DbStore& rStore, fsize_type nAdr );
> DbAutoPtr( DbStore& rStore, fsize_type nAdr, size_type nSize );
> ~DbAutoPtr( );
>
> // Operators
> T* operator->( );
> const T* operator->( ) const;
> DbAutoPtr< T >& operator=( const DbBasePtr& rP );
>
> T& operator*( );
> const T& operator*( ) const;
>
> bool isNull( ) const;
unnecessary and unnatural - it should work like an ordinary ptr
>
> fsize_type address( );
> fsize_type address( ) const;
> size_type size( ) const;
> void setAddress( fsize_type nAdr );
> void setSize( size_type nSize );
> bool loadData( );
> bool writeData( );
All this stuff above belongs somewhere else.
>
> const DbBasePtr * basePtr( ) const;
?
>
> // protected:
> const T * pointer( ) const;
> T * pointer( );
>
> protected:
> DbRefCount< DbBasePtr > _oData; // Object data
How does this work then?
> };
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline DbAutoPtr<T>::DbAutoPtr( )
> //////////////////////////////////////////////////////////////////////////
> {
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline DbAutoPtr<T>::DbAutoPtr( DbStore& rStore, fsize_type nAdr )
> //////////////////////////////////////////////////////////////////////////
> {
> _oData = DbBasePtr( rStore, nAdr, sizeof( T ) );
> _oData->loadData( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline DbAutoPtr<T>::DbAutoPtr( DbStore& rStore, fsize_type nAdr,
> size_type nSize )
> //////////////////////////////////////////////////////////////////////////
> {
> _oData = DbBasePtr( rStore, nAdr, nSize );
> _oData->loadData( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline DbAutoPtr<T>::~DbAutoPtr( )
> //////////////////////////////////////////////////////////////////////////
> {
> if( !_oData.isNull() )
> _oData->writeData( T::Clsid() );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline DbAutoPtr< T >& DbAutoPtr<T>::operator=( const DbBasePtr& rP )
> //////////////////////////////////////////////////////////////////////////
> {
> if( _oData.isNull() ) {
> _oData = rP;
> _oData->loadData( );
> }
> return *this;
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline const DbBasePtr * DbAutoPtr<T>::basePtr( ) const
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData.pointer();
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline T* DbAutoPtr<T>::pointer( )
> //////////////////////////////////////////////////////////////////////////
> {
> return (T*) _oData.pointer()->dataPointer();
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline const T* DbAutoPtr<T>::pointer( ) const
> //////////////////////////////////////////////////////////////////////////
> {
> return (const T*) _oData.pointer()->dataPointer();
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline const T* DbAutoPtr<T>::operator->() const
> //////////////////////////////////////////////////////////////////////////
> {
> return (const T*) pointer( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline T* DbAutoPtr<T>::operator->()
> //////////////////////////////////////////////////////////////////////////
> {
> return (T*) pointer();
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline const T& DbAutoPtr<T>::operator*() const
> //////////////////////////////////////////////////////////////////////////
> {
> V_ASSERT( pointer( ) );
> return *((const T*) pointer( ));
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline T& DbAutoPtr<T>::operator*()
> //////////////////////////////////////////////////////////////////////////
> {
> V_ASSERT( pointer( ) );
> return *((T*) pointer( ));
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline bool DbAutoPtr<T>::isNull( ) const
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData.isNull( ) || (0 == _oData->size( ) );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline fsize_type DbAutoPtr<T>::address( ) const
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData->address( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline size_type DbAutoPtr<T>::size( ) const
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData->size( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline fsize_type DbAutoPtr<T>::address( )
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData->address( T::Clsid() );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline void DbAutoPtr<T>::setAddress( fsize_type nAdr )
> //////////////////////////////////////////////////////////////////////////
> {
> _oData->setAddress( nAdr );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline void DbAutoPtr<T>::setSize( size_type nSize )
> //////////////////////////////////////////////////////////////////////////
> {
> _oData->setSize( nSize );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline bool DbAutoPtr<T>::loadData( )
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData->loadData( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline bool DbAutoPtr<T>::writeData( )
> //////////////////////////////////////////////////////////////////////////
> {
> return _oData->writeData( T::Clsid() );
> }
>
> #endif
> ==========
> // DbRefCount.h - compact reference counted class
>
> #ifndef _REFCOUNT_H_
> #define _REFCOUNT_H_
>
> #include <stdlib.h>
> #include "syTypes.h"
>
>
////////////////////////////////////////////////////////////////////////////
///
> // DbRefCount class
>
////////////////////////////////////////////////////////////////////////////
///
> template< class T >
> class DbRefCount {
> public:
> DbRefCount( );
> DbRefCount( const T& t );
> DbRefCount( const DbRefCount& rPtr );
> ~DbRefCount( );
>
> T* operator->( );
> const T* operator->( ) const;
> T& operator*( );
> const T& operator*( ) const;
> DbRefCount& operator=( const T& t );
> DbRefCount& operator=( const DbRefCount& rPtr );
> bool operator==( const DbRefCount& rPtr ) const;
> bool isNull( ) const;
>
> // protected:
> const T * pointer( ) const;
> T * pointer( );
> void copyFrom( const DbRefCount& rSrc);
> void release( );
> void * alloc( size_t nSize );
>
> protected:
> int * _pPtr;
> };
>
>
////////////////////////////////////////////////////////////////////////////
///
> template< class T >
> inline DbRefCount< T >::DbRefCount( ) : _pPtr( NULLPTR )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template< class T >
> inline DbRefCount< T >::DbRefCount( const T& t ) : _pPtr( NULLPTR )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> T * p = new( alloc( sizeof(T) ) ) T( t );
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template< class T >
> inline DbRefCount< T >::DbRefCount( const DbRefCount< T >& rPtr )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> copyFrom( rPtr );
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template< class T >
> inline DbRefCount< T >::~DbRefCount( )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> release( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline const T* DbRefCount<T>::operator->() const
> //////////////////////////////////////////////////////////////////////////
> {
> return pointer( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline T* DbRefCount<T>::operator->()
> //////////////////////////////////////////////////////////////////////////
> {
> return pointer( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline const T& DbRefCount<T>::operator*() const
> //////////////////////////////////////////////////////////////////////////
> {
> V_ASSERT( pointer( ) );
> return *pointer( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> template<class T>
> inline T& DbRefCount<T>::operator*()
> //////////////////////////////////////////////////////////////////////////
> {
> V_ASSERT( pointer( ) );
> return *pointer( );
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline const T * DbRefCount< T >::pointer( ) const
>
////////////////////////////////////////////////////////////////////////////
///
> {
> V_ASSERT( _pPtr );
> return (const T *) (_pPtr + 1);
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline T * DbRefCount< T >::pointer( )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> return _pPtr ? (T *) (_pPtr + 1) : NULLPTR;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline DbRefCount< T >& DbRefCount< T >::operator =( const T& t )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> if( NULLPTR == _pPtr )
> new( alloc( sizeof(T) ) ) T( t );
> return *this;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline DbRefCount< T >& DbRefCount< T >::operator=( const DbRefCount<
> T >& rPtr )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> if( &rPtr != this ) {
> release( );
> copyFrom( rPtr );
> }
> return *this;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline bool DbRefCount< T >::operator==( const DbRefCount< T >& rRhs )
> const
>
////////////////////////////////////////////////////////////////////////////
///
> {
> return _pPtr == rRhs._pPtr;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline bool DbRefCount< T >::isNull( ) const
>
////////////////////////////////////////////////////////////////////////////
///
> {
> return _pPtr == NULLPTR;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline void DbRefCount< T >::release( )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> if( _pPtr ) {
> (*_pPtr)--;
> if( *_pPtr == 0 ) {
> T * tp = pointer( );
> tp->~T( );
> ::free( _pPtr );
> _pPtr = NULLPTR;
> }
> }
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline void DbRefCount< T >::copyFrom( const DbRefCount< T >& rSrc )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> _pPtr = rSrc._pPtr;
> if( _pPtr ) (*_pPtr)++;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> template<class T>
> inline void * DbRefCount< T >::alloc( size_t nSize )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> int * pPtr = (int *) ::realloc( _pPtr, nSize + sizeof(int) );
> if( NULLPTR == _pPtr ) {
> *pPtr = 1;
> }
> _pPtr = pPtr;
> return _pPtr + 1;
> }
>
> #endif
> =======
> // DbBasPtr.h
>
> #ifndef _DBBASPTR_H_
> #define _DBBASPTR_H_
>
> #include "syTypes.h"
> #include "DbDefs.h"
> #include "DbObjRef.h"
>
> class DbStore;
>
>
////////////////////////////////////////////////////////////////////////////
///
> // DbBasePtr
>
////////////////////////////////////////////////////////////////////////////
///
> class DbBasePtr : public DbObjRef {
> public:
> DbBasePtr( DbStore& rStore, fsize_type nAdr, size_type nSize );
> ~DbBasePtr( );
>
> const void * dataPointer( ) const;
> void * dataPointer( );
> fsize_type address( clsid_type nClsid );
> fsize_type address( ) const;
>
> // protected:
> bool loadData( );
> bool writeData( clsid_type nClsid );
> void * alloc( size_type nSize );
>
> protected:
> DbStore * _pStore;
> void * _pData; // Object data
> };
>
>
////////////////////////////////////////////////////////////////////////////
///
> inline DbBasePtr::DbBasePtr( DbStore& rStore, fsize_type nAdr,
> size_type nSize )
> : DbObjRef( nAdr, nSize ), _pStore( &rStore ),
> _pData( NULLPTR )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> inline DbBasePtr::~DbBasePtr( )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> inline const void * DbBasePtr::dataPointer( ) const
>
////////////////////////////////////////////////////////////////////////////
///
> {
> return _pData;
> }
>
>
////////////////////////////////////////////////////////////////////////////
///
> inline void * DbBasePtr::dataPointer( )
>
////////////////////////////////////////////////////////////////////////////
///
> {
> setDirty( );
> return _pData;
> }
>
> //////////////////////////////////////////////////////////////////////////
> inline fsize_type DbBasePtr::address( ) const
> //////////////////////////////////////////////////////////////////////////
> {
> return DbObjRef::address( );
> }
>
> //////////////////////////////////////////////////////////////////////////
> inline fsize_type DbBasePtr::address( clsid_type nClsid )
> //////////////////////////////////////////////////////////////////////////
> {
> writeData( nClsid );
> return DbObjRef::address( );
> }
>
> #endif
- Previous message: Kevin Goodsell: "Re: ifstream"
- In reply to: Virendra Verma: "Re: Destructor for const object"
- Next in thread: Virendra Verma: "Re: Destructor for const object"
- Reply: Virendra Verma: "Re: Destructor for const object"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|