Hi there,
I am writing a smart pointer that is similar to the boost intrusive ptr.
I am trying to make it behave like a c++ pointer including the implicit
and explicit casting behaviour.
Below is the part more or less relevant to my problem.
Version 1 is fine for casting to a derived class, but it must be called
explicitly even though it is used to cast to a base class.
Version 2 is fine for implicitly casting to a base class, but will never
cast to a derived class
Version 3 is really bad. It will cast to a derived class implicitly,
which is not what I want.
I cannot use 1 and 2 the same time, or is there a workaround that makes
the compiler think of them as different members?
template<typename T>
class THE_API Ref
{
public:
Ref( void ) : _pObj( NULL ) { }
Ref( T* Source ) {_set( Source ); }
Ref( const Ref<T>& Source ) {_set( Source._pObj ); }
// Version 1. would cast only explicitly
template< typename CASTTYPE > explicit
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*>( Source.GetNativePtr( ) ) );
}
// Version 2. is implicit and performs an implicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( Source.GetNativePtr( ) );
}
// Version 3. is implicit but performs an explicit cast
template< typename CASTTYPE >
Ref( const Ref<CASTTYPE>& Source )
{
_set( static_cast<T*>( Source.GetNativePtr( ) ) );
}
template< typename CASTTYPE >
explicit
Ref( CASTTYPE* source )
{ // error C2440: Did you cast T* to Ref<Ref<T> > ?
_set( static_cast<T*>( source ) );
}
private:
void _dec( ) { if( _pObj ) if ( !(--(_pObj->_refCount) ) )
delete _pObj; }
void _inc( ) { if( _pObj ) ++(_pObj->_refCount); }
void _set( T* Ptr ) { _pObj = Ptr; _inc( ); }
};