C ++智能指针自己的实现

时间:2011-08-25 18:56:07

标签: c++ smart-pointers

假设您使用的是无法使用TR1,boost等的系统。您只需使用直接标准库C ++。

如果您遇到这种情况,您可以使用的最简单的引用计数智能指针是什么? (我们的系统只有auto_ptr,它不太有用)。

如果这是一个答案(我一半期待:()),我很高兴能找到一些有些成熟的东西或简单的“实现自己太复杂”的链接。

3 个答案:

答案 0 :(得分:4)

我可能会选择std::shared_ptr,这是两周前在C ++ 0x中批准的(所以不需要TR1)。严肃地说,我会建议boost(或升级)。你当然可以自己实现它,但成本效益没有意义,因为这样的结构很难做到。

答案 1 :(得分:2)

前段时间我刚开始研究兴趣。它不是那么“聪明”,但无论如何比原始指针更好。

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;
 }
};

是的,这只是演示..

答案 2 :(得分:0)

如果你很幸运,那么你还没有设计出需要共享指针的类,但没有现成的类。 如果你很幸运,你的整个程序将以单线程运行......

然后你有机会拥有一个非常便宜的共享指针。

使用基类SharedPtr。从中导出所有对象。 SharedPtr类型的对象将包含一些用于计数的免费存储内存。 复制时,请进行增量 当你正在摧毁它时,如果必要的话减少并释放物体。 Et cetra et cetra of the shared pointer semantics。

将指针存储为SharedPtr。并在需要某些操作时进行向下转换。

我知道这是廉价的解决方案,但......  1.多线程需要锁定。费用+参与。  2.模板编程。可能需要半天和另外半天来调试和修复您的问题,当您尝试从BOOST复制shared_ptr时,您将获得该问题

如果你只有几个类的存在更重要而没有数百个操作,那么你可以尝试这种方法。

不过,这是一种“模板模式”