2011-08-25 117 views
2

假設你在一個你不能使用TR1,boost等的系統上。你只有直接的標準庫C++。C++智能指針自己的實現

如果您遇到這種情況,您可以使用哪種最簡單的引用計數智能指針? (我們的系統只有auto_ptr,它不是非常有用)。

我很高興與鏈接到的東西有點成熟或簡單的「這是過於複雜,實現自己」如果是這樣的答案(這我是期待:()。

+6

難道你不能去提升和複製和粘貼他們的智能指針到你的代碼庫嗎? –

+0

您的應用程序是否保證爲單線程,永遠和永恆? –

+2

在哪種情況下你不能使用boost?不是'shared_ptr'頭文件? – KillianDS

回答

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

,是的,它只是演示..

+0

我們是否需要虛擬析構函數?我也會添加「重置」。如果不是,它的使用是有點限制國際海事組織。 – Jagannath

+0

@jagansai。可能你是對的。你知道這只是爲了學習目的而不是用法:) – legion

+1

那麼,它只是一個學習解決方案,但我很欣賞這種努力。我發現了一個很好的專家交換文章由evilrix @ http://www.experts-exchange.com/Programming/Languages/CPP/A_1959-C-Smart-pointers.html與一個非常詳細的智能指針實現這就是這樣,如果你'感興趣。無論如何,我接受:)這是一個非庫智能指針的好起點。謝謝! –

4

我可能會去std::shared_ptr,它在兩個星期前被C++ 0x批准了(所以沒有TR1需要)。總之,我會推薦boost(或者升級)。你當然可以可以自己實現,但是成本效益不會沒有道理,因爲像這樣的構造很難做對。

0

如果幸運的話,那麼你還沒有設計出需要共享指針,但不類有一個現成的一個。 如果你很幸運,你的整個程序將運行在單線程...

然後你有機會有一個非常便宜的共享指針。

使用基類SharedPtr。從中導出所有對象。 SharedPtr類型的對象將包含一些用於計數的自由存儲內存。 當您複製它時,請增加 當您銷燬它時,如果需要的話減量並釋放該對象。共享指針語義的等級和等級。

將指針存儲爲SharedPtr。並在需要某些操作時進行向下傾倒。

我知道這是便宜的解決方案,但... 1.多線程將需要鎖。代價高昂+涉及。 2.模板編程。可能需要半天和半天的時間來調試和解決你的問題,當你嘗試從BOOST複製shared_ptr時會得到這些問題。

如果你只有幾個類,它們的存在更重要,而不是數百對他們的操作,那麼你可以嘗試這種方法。

順便說一句,這是一種「模板模式」