开发者

C++ Smart pointer own implementation

Let's say that you're on a system where you cant use TR1, boost, etc. You just have the straight-up standard library C++.

If you were stuck with this scenario, what's the simplest reference-counting smart-pointer you could use? (our system only has auto_ptr which is not overly useful).

I'm happy with a link to something so开发者_如何学Cmewhat well-established or a simple "it's too complicated to implement yourself" if that's the answer (which I'm half expecting :( ).


I would probably go with std::shared_ptr, which was approved in C++0x two weeks ago (so no TR1 needed). In all seriousness, I would recommend boost (or upgrading). You certainly can implement it yourself, but the cost-benefit doesn't make sense, since constructs like this are complicated to do right.


Well some time ago I just made one for studding interest. It's not so "smart" but anyway better then raw pointer.

class CReferenceCount
{
private:
    unsigned int m_count;

public:
   CReferenceCount() : m_count(0) { }
   virtual ~CReferenceCount() { }

   void increseRef()
   {
      ++m_count;
   }

   unsigned int decreseRef()
   {
      return --m_count;
   }
};

class CCustomDeleter
{
public:
  template<typename T>
  void operator()(const T* ptr) const
  {
      delete ptr; ptr = NULL;
  }

  void operator()(const char* ptr) const
  {
     delete[] ptr; ptr = NULL;
  }
};

template <typename T>
class CWrapPtr
{
private:
 void makeRefCountObj()
 {
    try
    {
        m_rcPtr = new CReferenceCount();
    }
    catch (std::bad_alloc &err)
    {
        std::cout<<"-- CWrapPtr : "<<err.what()<<std::endl;
        // should do something about failed CWrap object...
    }

    m_rcPtr->increseRef();
 }

 public:
  T *m_objPtr;
  CReferenceCount *m_rcPtr;


  CWrapPtr() : m_objPtr(NULL), m_rcPtr(NULL)
  {
     makeRefCountObj();
  }

  CWrapPtr(T *obj) : m_objPtr(obj), m_rcPtr(NULL)
  {
     makeRefCountObj();
  }

  virtual ~CWrapPtr()
  {
    if (m_rcPtr && m_rcPtr->decreseRef() == 0)
    {
        CCustomDeleter dd;
        dd(m_objPtr);

        delete m_rcPtr; m_rcPtr = NULL;
    }
  }

  CWrapPtr(const CWrapPtr<T> &other) : m_objPtr(other.m_objPtr),
                                     m_rcPtr(other.m_rcPtr)
  {
      m_rcPtr->increseRef();
  }


T& operator*()
{
    assert(m_objPtr != NULL);
    return *m_objPtr;
}

T* operator->()
{
    assert(m_objPtr != NULL);
    return m_objPtr;
}

CWrapPtr<T>& operator=(const CWrapPtr<T> &other)
{
    if (this != &other)
    {

        if (m_rcPtr && m_rcPtr->decreseRef() == 0)
        {
            CCustomDeleter dd;
            dd(m_objPtr);

            delete m_rcPtr; m_rcPtr = NULL;
        }

        m_objPtr = other.m_objPtr;
        m_rcPtr = other.m_rcPtr;

        m_rcPtr->increseRef();
    }

    return *this;
 }
};

And yeah it's just demo..


If you are lucky, then you havent designed the classes that need shared pointer but dont have a readymade one. If you are lucky and your entire program will run in single thread ...

Then you have chance of having a really cheap shared pointer.

Use a base class SharedPtr. Derive all the object from that. Objects of type SharedPtr will contain some free-store memory for counting. When you are copying it, do increment When you are destroying it decrement and free the object if necessary. Et cetra et cetra of the shared pointer semantics.

Store pointers as SharedPtr. and do downcast whenever you need some operation.

I know this is cheapo solution, but... 1. Multithreaded will require locks. Costly + involved. 2. Template programming. Will probably require a half-day and another half day to debug and fix your issues, which you will get when you try to replicate shared_ptr from BOOST

If yo uhave just couple of classes whose existence is more important and not with hundreds of operations on them, then you can try this approach.

Btw, this is kind of "template-pattern"

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜