Hey all,
I got interested in using smart pointers and tried to implement the following solution: http://www.davethehat.com/articles/smartp.htm
It's probably far from perfect but this is mainly a learning experience.
It's a non intrusive reference counted implementation of a smart ptr. And somewhere in the article the assignment operator is defined:
template<class T>
ObjVar<T>& operator=(const ObjVar<T>& rVar)
{
if (!rVar.Null())
rVar.m_pCounted->GetRef();
UnBind();
m_pCounted = rVar.m_pCounted;
return *this;
}
the m_pCounted object is a pointer to the following class:
template <class T> class Objvar;
template <class T>
class Counted
{
friend class ObjVar<T>;
private:
Counted(T* pT) : Count(0), my_pT(pT)
{ ASSERT(pT != 0); }
~Counted() { ASSERT(Count == 0); delete my_pT; }
unsigned GetRef() { return ++Count; }
unsigned FreeRef() { ASSERT(Count!=0); return --Count; }
T* const my_pT;
unsigned Count;
};
When you put the code in the article together everything seems to work fine but assignment of a derived class smart ptr to a base class smart ptr seems to fail:
ObjVar<CBaseClass> basePtr;
ObjVar<CDerivedClass> derivedPtr;
basePtr = derivedPtr;
It fails because the compiler complains about the following assignment in the assignment operator of the ObjVar class:
m_pCounted = rVar.m_pCounted;
In this case m_pCounted would be of type: Counted<CBaseClass> * and the rVar.m_pCounted is of type: Counted<CDerivedClass> *. How can I make this assignment work? It seems valid that the compiler is complaining because the template arguments are different but it somehow doesn't make sense to me since the types are closely related. After all, we are allowed to do something like:
CBaseClass *basePtr;
CDerivedClass *derivedPtr;
basePtr = derivedPtr;