Introduction
Shared pointer is a class which can share the underlying data between object. This avoids deep copying and improves performance. It is also called as shallow copying.
Smart pointer is a class which manages the life time of the underlying pointer.
A simple smart pointer class
Lets create a simple base class for smart pointer class using c++ template so that we can store any type of data.
The basic idea of a shared pointer or a smart pointer is that actual data is stored separately and the shared pointer or smart pointer class will have a pointer to it.
For a very basic shared pointer class will have the data class as,
class Data { public: int mRefCount; T mData; };
template < typename T > class RSharedObject { protected: class Data { public: int mRefCount; T mData; }; public: RSharedObject() : mData(0) {} RSharedObject(RSharedObject const & o) { mData = 0; copy(o); } RSharedObject& operator=(RSharedObject const & o) { copy(o); return *this; } // ... };
template <typename T > class RSharedObject { protected: class Data { public: int mRefCount; T mData; }; public: RSharedObject() : mData(0) {} RSharedObject(RSharedObject const & o) { mData = 0; copy(o); } RSharedObject& operator=(RSharedObject const & o) { copy(o); return *this; } virtual ~RSharedObject() { dispose(); } protected: virtual T & data_p() { if (!mData) { create(); } return mData->mData; } virtual const T & data_p() const { if (!mData) { const_cast*>(this)->create(); } return mData->mData; } void copy(RSharedObject const & oth) { dispose(); mData = oth.mData; ref(); } void detach() { if (mData && mData->mRefCount > 1) { deref(); mData = new Data(*mData); mData->mRefCount = 1; } } private: void create() { mData = new Data(); ref(); } void dispose() { if (mData) { deref(); if (mData->mRefCount == 0) { delete mData; mData = 0; } } } void ref() { if (mData) { ++mData->mRefCount; } } void deref() { if (mData) { --mData->mRefCount; } } private: Data * mData; };
Function data_p will be used to access the actual data from the derived classes.
Lets create a detachable shared object class. Detachable shared object class detaches itself from the underlying pointer data if required.
template <typename T > class RDetachableRSharedObject: RSharedObject{ protected: T & data_p() { this->detach(); return RSharedObject ::data_p(); } const T & data_p() const { return RSharedObject ::data_p(); } };
Then smart pointer class
We will create a base class for smart pointer so that we can have smart pointer class for both object and array.
This smart pointer base class will derive from our RSharedObject class.
template <typename A, typename D > class RSmartPointerBase: public RSharedObject < A > { public: RSmartPointerBase(D * p) { this->data_p().mPtr = p; this->data_p().mOwn = true; } bool isNull() const { return data() == 0; } D * data() { return this->data_p().mPtr; } const D * data() const { return this->data_p().mPtr; } D * take() { this->data_p().mOwn = false; return this->data_p().mPtr; } D * operator->() { return data(); } const D * operator->() const { return data(); } D & operator*() { return *(data()); } const D * operator*() const { return *(data()); } };
Lets now create the actual smart pointer,
template < typename D > class RSmartPointerData { public: RSmartPointerData() : mOwn(true), mPtr(0) {} ~RSmartPointerData() { if (mOwn) { delete mPtr; } } private: RSmartPointerData(RSmartPointerData const &); RSmartPointerData & operator=(RSmartPointerData const &); public: bool mOwn; D * mPtr; }; template < typename D > class RSmartPointer: public RSmartPointerBase<RSmartPointerData<D>, D> { public: RSmartPointer(D * p=0) : RSmartPointerBase, D>(p) {} operator D*() { return this->data(); } operator const D*() const { return this->data(); } };
Lets now create the actual smart array pointer,
template < typename D > class SmartArrayPointerData { public: SmartArrayPointerData() : mOwn(true), mPtr(0) {} ~SmartArrayPointerData() { if (mOwn) { delete [] mPtr; } } private: SmartArrayPointerData(SmartArrayPointerData const &); SmartArrayPointerData & operator=(SmartArrayPointerData const &); public: bool mOwn; D * mPtr; }; template <typename D > class SmartArrayPointer: public RSmartPointerBase< SmartArrayPointerData<D>, D> { public: SmartArrayPointer(D * p=0) : RSmartPointerBaseI know it is more code and less document, but hopefully it helps., D>(p) {} operator D*() { return this->data(); } operator const D*() const { return this->data(); } };
Complete implementation can be found at https://github.com/trsquarelab/glexamples/blob/master/src/common/rsmart_pointer.h
Great! Shared with my devs! thanks. Another question - is dataroom services your sphere of interest? Should I await for some reviews on this topic? Thanks in advance
ReplyDelete