I am trying to improve my general skills in C++ so I plan to write versions of shared_ptr and unique_ptr from scratch. I wrote a version of shared_ptr with reference counting and I was wondering for reviews.
#ifndef __SHIVA_XSMARTPTRS__
#define __SHIVA_XSMARTPTRS__
/*
This tries to define a reference counted smart pointer class instead of
regular pointers
*/
namespace Shiva
{
template <class T>
class SmartPtr
{
public:
//Default Constructor
explicit SmartPtr(T* p = 0)
{
if(p)
ptrWrapper_ = new PointerWrapper(p,1);
else
ptrWrapper_ = new PointerWrapper();
}
//The copy constructor
SmartPtr(const SmartPtr& copyObj)
{
ptrWrapper_ = copyObj->ptrWrapper_;
ptrWrapper_->incrementRefCount();
}
//Assignment operator
SmartPtr& operator=(const SmartPtr& copyObj)
{
if(this != copyObj)
{
//Decrement and decimate as needed
unsigned int preReleaseRefCount = ptrWrapper_->getRefCount();
ptrWrapper_->decrementRefCount();
if(preReleaseRefCount==1)
{
delete ptrWrapper_;
ptrWrapper_ = 0;
}
ptrWrapper_ = copyObj->ptrWrapper_;
ptrWrapper_->incrementRefCount();
}
return *this;
}
//The main object destructor
//Essentially decrement the refcount by 1. If the refcount is equal to 0, then you should delete the pointer
~SmartPtr()
{
unsigned int preReleaseRefCount = ptrWrapper_->getRefCount();
ptrWrapper_->decrementRefCount();
if(preReleaseRefCount==1)
{
delete ptrWrapper_;
ptrWrapper_ = 0;
}
}
//Referncing operator
T& operator*()
{
return ptrWrapper_->getReference();
}
//Address operator
T* operator->()
{
return ptrWrapper_->getPointer();
}
//Get reference counter
int getRefCount() const
{
return ptrWrapper_->getRefCount();
}
//Is this the only copy of the object present
bool unique() const
{
return ptrWrapper_->isUnique();
}
private:
class PointerWrapper
{
public:
PointerWrapper(T* ptr=0, int refCount = 0)
:ptr_(ptr),refCount_(refCount)
{}
T* getPointer()
{
return ptr_;
}
T& getReference()
{
return *ptr_;
}
unsigned int getRefCount()
{
return refCount_;
}
void decrementRefCount()
{
refCount_--;
if(!refCount_)
{
delete ptr_;
ptr_ = 0;
}
}
void incrementRefCount()
{
refCount_++;
}
bool isUnique()
{
return (refCount_==1);
}
private:
T* ptr_;
int refCount_;
};
PointerWrapper* ptrWrapper_;
};
}
#endif