   Template RefCountPointer Cast/Polymorphism Problem
  Hi there,I'm playing around with a custom Reference Counted Pointer class and ran into a problem.RefCountPointer< T >  | v    RefCountData< T > ^ |RefCountPointer< T >Each RefCountPointer instance holds a pointer to the same RefCountData instance, which stores a count variable and a raw pointer to the encapsulated object.So far so good, but I want to extend this to allow polymorphism like this:RefCountPointer< Derived > pDerived( new Derived() );RefCountPointer< Base > pBase( pDerived );Now within "RefCountPointer< T >::RefCountPointer( RefCountPointer< U > pIn )" i need to somehow cast the RefCountData< U > to a RefCountData< T > to work properly, but I'm running out of ideas right now.. Would be nice if someone of you could push me into the right direction.. Here's a short example illustrating my current attempt which doesn't work (as far as I can tell reinterpret_cast messes around with the vtable):struct Base1{virtual ~Base1() {};virtual void Test1() = 0;};struct Base2{virtual ~Base2() {};virtual void Test2() = 0;};struct Derived : public Base1, public Base2{Derived() : Base1(), Base2() {};virtual ~Derived() {};virtual void Test1() {};virtual void Test2() {};};template< typename T >struct Container{T*m_Ptr;};int main( int, char** ){Derived* pDerived = new Derived();// Following Method Calls WorkpDerived->Test1();pDerived->Test2();// UpCast Of pDerived To A Base1 PointerBase1* pBase1 = pDerived;// Following Method Call WorkspBase1->Test1();// UpCast Of pDerived To A Base1 PointerBase2* pBase2 = pDerived;// Following Method Call WorkspBase2->Test2();// Up Until Now Everything Works As Expected, Now I'm Trying To Do// The Same, But Instead Of Using Raw Pointers, I Encapsulate Them// In The Template-Container.// Encapsulating pDerived In A ContainerContainer< Derived >* pContainerDerived = new Container< Derived >();pContainerDerived->m_Ptr = pDerived;// Following Method Calls WorkpContainerDerived->m_Ptr->Test1();pContainerDerived->m_Ptr->Test2();// Brute Force Cast Of The Derived Container To A Base1 Container.. Is There Another Way?Container< Base1 >* pContainerBase1 = reinterpret_cast< Container< Base1 >* >( pContainerDerived );// Following Method Call WorkspContainerBase1->m_Ptr->Test1();// Brute Force Cast Of The Derived Container To A Base2 Container .. Is There Another Way?Container< Base2 >* pContainerBase2 = reinterpret_cast< Container< Base2 >* >( pContainerDerived );// ERROR! Following Method Calls Test1()... =[pContainerBase2->m_Ptr->Test2();// Clean Up The Mess;delete pContainerDerived;delete pDerived;return 0;}
  Why is RefCountData< T > templated? It's an internal data structure for which you can ensure type safety in RefCountPointer.It's just a std::pair<void *, unsigned int> type of tuple. It doesn't care about types, only about the count.   ;  Hi, are you sure it calls Test1 instead of Test2 ? I'm not sure, but maybe the compiler makes no difference between 2 empty methods, both void and no parameters. Have you tried with some code in those methods ?About the cast, I can't find any problem with it. But I think a template constructor for RefCountData could do it :template<class T>;class RefCountData{...template<class U>; RefCountData(RefCountData<U>& other){ // the cast comes here }...}so you should be able to do this :Container<Base2>* pContainerBase2 = pContainerDerived;Maybe I'm all wrong...   ;  Antheus' suggestion interacts badly with multiple inheritance. However, there's a lot of truth in what he says: give your class a pointer to the stored object and a pointer to a shared reference count integer. This is equivalent to adding a a global reference field with another level of indirection to your RefCountData object.   ;  Add a conversion operator for implicit casts.template< typename T >struct Container{T* m_Ptr;template<typename T1>Container(Contaner<T1>& rhs):m_Ptr(rhs.m_Ptr){}};Container< Base2 > pContainerBase2(pContainerDerived);I dont really understand why you are using pointers to Container classes, you also want to look at overloading operators such as "=" "->" "*" "bool" etc.;  Hi again, thx for all your replies.Quote:Original post by ToohrVykAntheus' suggestion interacts badly with multiple inheritance. However, there's a lot of truth in what he says: give your class a pointer to the stored object and a pointer to a shared reference count integer. This is equivalent to adding a a global reference field with another level of indirection to your RefCountData object.If I understood you correctly, you suggest adding T* as a member to each RefCountPtr<T> instance. This way it's possible to un-template RefCountData which is shared.A very simple solution. I got it working below. I still need a reinterpret_cast, but I guess it's safe if there's no vtable involved.Right now this will get me going. I think i'll have to look into boost::shared_ptr later on to find out how they did it; adding a ptr-member to each RefCountPtr instance seems like redundant data.First the Non-Working example:#include <iostream>template< typename T > class RefCountPtr{template< typename T >class RefCountData;   // Private Inner Class Forward Declarationtemplate< typename U >friend class RefCountPtr;  // Enable Access To RefCountData* Of Other RefCountPtr Typespublic:RefCountPtr( T* ptr ):m_pRefCountData( new RefCountData< T >( ptr ) ){m_pRefCountData->AddCount();}RefCountPtr( const RefCountPtr< T >& in ):m_pRefCountData( in.m_pRefCountData ){m_pRefCountData->AddCount();}template< typename U >RefCountPtr( const RefCountPtr< U >& in ){// Getting Rid Of The const...RefCountPtr< U > constHack( in );// Evil Castm_pRefCountData = reinterpret_cast< RefCountData< T >* >( constHack.m_pRefCountData );m_pRefCountData->AddCount();}~RefCountPtr(){m_pRefCountData->RemoveCount();}T* operator->() const{return m_pRefCountData->GetPtr();}T& operator*() const{return *( m_pRefCountData->GetPtr() );}private:RefCountData< T >*m_pRefCountData;private:template< typename T >class RefCountData{public:RefCountData( T* ptr ):m_Ptr( ptr ), m_nCount( 0 ){}void AddCount() { ++m_nCount;};void RemoveCount() {if( --m_nCount == 0 ){delete m_Ptr;delete this;// "delete this" Works If The DTor Is Empty// And If "this" Won't Be Accessed Afterwards}};T* GetPtr(){return m_Ptr;};private:T*   m_Ptr;unsigned intm_nCount;};};struct Base1{virtual ~Base1() {};virtual void Test1() = 0;};struct Base2{virtual ~Base2() {};virtual void Test2() = 0;};struct Derived : public Base1, public Base2{Derived() : Base1(), Base2() {};virtual ~Derived() {};virtual void Test1() { std::cout << "Test1\n";};virtual void Test2() { std::cout << "Test2\n";};};int main( int, char** ){// OkRefCountPtr< Derived > pDerived( new Derived() );pDerived->Test1();pDerived->Test2();// OkRefCountPtr< Base1 > pBase1( pDerived );pBase1->Test1();// Error, Calls Test1() !!RefCountPtr< Base2 > pBase2( pDerived );pBase2->Test2();// Output://// Test1// Test2// Test1// Test1return 0;}Now the Working example:- RefCountData now only holds the counter, no template needed.- each RefCountPointer holds a copy of the pointer to the encapsulated object#include <iostream>template< typename T > class RefCountPtr{class RefCountData;// Private Inner Class Forward Declarationtemplate< typename U >friend class RefCountPtr;    // Enable Access To RefCountData* Of Other RefCountPtr Typespublic:RefCountPtr( T* ptr ):m_pRefCountData( new RefCountData() ), m_Ptr( ptr ){m_pRefCountData->AddCount();}RefCountPtr( const RefCountPtr< T >& in ):m_pRefCountData( in.m_pRefCountData ), m_Ptr( in.m_Ptr ){m_pRefCountData->AddCount();}template< typename U >RefCountPtr( const RefCountPtr< U >& in ){// Getting Rid Of The const...RefCountPtr< U > constHack( in );// Evil Cast, but i guess it's safe nowm_pRefCountData = reinterpret_cast< RefCountPtr< T >::RefCountData* >( constHack.m_pRefCountData );m_Ptr = in.m_Ptr;m_pRefCountData->AddCount();}~RefCountPtr(){if( m_pRefCountData->RemoveCount() == 0 ){delete m_pRefCountData;delete m_Ptr;}}T* operator->() const{return m_Ptr;}T& operator*() const{return *( m_Ptr );}private:T*m_Ptr;RefCountData*m_pRefCountData;private:class RefCountData{public:RefCountData():m_nCount( 0 ){}unsigned int AddCount() { return ++m_nCount;};unsigned int RemoveCount() {return --m_nCount;};private:unsigned intm_nCount;};};struct Base1{virtual ~Base1() {};virtual void Test1() = 0;};struct Base2{virtual ~Base2() {};virtual void Test2() = 0;};struct Derived : public Base1, public Base2{Derived() : Base1(), Base2() {};virtual ~Derived() {};virtual void Test1() { std::cout << "Test1\n";};virtual void Test2() { std::cout << "Test2\n";};};int main( int, char** ){// OkRefCountPtr< Derived > pDerived( new Derived() );pDerived->Test1();pDerived->Test2();// OkRefCountPtr< Base1 > pBase1( pDerived );pBase1->Test1();// Ok!! :DRefCountPtr< Base2 > pBase2( pDerived );pBase2->Test2();// Output://// Test1// Test2// Test1// Test2return 0;};  You could also choose to inherit RefCountData<T> from a shared RefCountDataBase class that is independent of T and implements the basic "reference-count" protocol and self-destructs when applicable:namespace impl {class RefCountDataBase {  int refs;public:  RefCountDataBase() : refs(1) {}  void AddCount() { ++refs; }  void RemoveCount() { if (--refs == 0) delete this; }  virtual ~RefCountDataBase() {}};template&lt;typename T&gt;class RefCountData : public RefCountDataBase {  std::auto_ptr&lt;T&gt; data;public:  RefCountData(T *ptr) : data(ptr) {}};} // namespace implNote that I dropped the "get pointer" member, because you don't need it (the pointer is already available in your pointer classes).   ;  Is reinterpret_cast even correct here? Wouldn't dynamic_cast (or static_cast, if type is known at compile time) be more appropriate?Doesn't reinterpret_cast simply mean "treat X bits as Y bits"? While dynamic_cast deals with all the inheritance checking and whatnot?   ;  Hello ZuBsPacE,Moving the definition of RefCountData out of the templated class RefCountPointer would allow you to lose the reinterpret_cast from your second example (in your most recent post). This could then be placed: at file scope or inside a namespace, For example: namespaced to avoid adding to the global namespace.namespace RefCountPointerImpl{  class RefCountData   {    ...  };}template< typename T > class RefCountPtr{  typedef RefCountPointerImpl::RefCountData RefCountData;  ...}; Cheers.Tom   ;  Thank you all for your wonderful suggestions :)@ToohrVyk: I like your idea, looks very clean and allows me to get rid of the reinterpret_cast!@ravyne2001: yeah, reinterpret_cast should be avoided if possible. Now I realized that it's cleaner to make unrelated template classes inherit from a common parent class which provides the interface, if possible. dynamic_cast could probably simplify the process, but I'm trying to avoid enabling RTTI.   