1. 程式人生 > >C++ RCSP智能指針簡單實現與應用

C++ RCSP智能指針簡單實現與應用

自定義類 例子 定義 memcpy 智能指針 cto ted 分配 思路

智能指針的實現代碼來源博客:《http://blog.csdn.net/to_be_better/article/details/53570910》

修改:添加 get()函數,用以獲得原始指針(raw pointer)。

其余思路來源《Effective C++》

智能指針的實現代碼如下:

template <typename T>
class SmartPtr;
template <typename T>
class Ptr
{
    friend class SmartPtr<T>;

    T *m_ptr;
    size_t m_count;

    Ptr(T 
*p = NULL) : m_ptr(p), m_count(1) {} ~Ptr() { delete m_ptr; } }; template <typename T> class SmartPtr { public: SmartPtr(T *p = NULL) : m_p(new Ptr<T>(p)) {} SmartPtr(const SmartPtr &sp) : m_p(sp.m_p) { ++m_p->m_count; } SmartPtr
&operator=(const SmartPtr &sp) { ++sp.m_p->m_count; if (--m_p->m_count == 0) { delete m_p; } m_p = sp.m_p; return *this; } T *operator->() { return m_p->m_ptr; } const T *operator->() const { return m_p->m_ptr; } T
operator*() { return *m_p->m_ptr; } T *get() /*get raw pointer*/ { return m_p->m_ptr; } ~SmartPtr() { if (--m_p->m_count == 0) delete m_p; } private: Ptr<T> *m_p; };

引用計數型智能指針(reference-counting smart pointer, RCSP)可實現持續追蹤共有多少對象指向某筆資源,並在無人指向它時自動刪除該資源。

在c++中資源管理中為防止意外退出而導致資源泄漏。

這種reference counting 可以允許copying行為,如需抑制copying,以private 方式繼承Uncopyable類即可。

Uncopyable類:

class Uncopyable
{
  protected:
    Uncopyable() {}
    ~Uncopyable() {}

  private:
    Uncopyable(const Uncopyable &);
    Uncopyable &operator=(const Uncopyable &);
};

一個應用例子:

目的是創建一個類的智能指針,用以描述文件的一些屬性的類,在後續代碼中使用這個指針來賦予或讀取這些屬性。當然,使用智能指針為了防止資源泄漏,符合本文初衷。

由成員函數:createFileAttrs() 產生動態創建一個靜態的智能指針,由這個指針去給類中的成員變量分配資源,並返回這個指針,即可實現功能。

測試類:

class FileAttr
{
public:
    ~FileAttr();
    static SmartPtr<FileAttr> createFileAttrs();
    char *md5;
private:
    FileAttr();
};
FileAttr::FileAttr()
{}
FileAttr::~FileAttr()
{
    cout << "destructor" << endl;
    delete[] md5;
}
SmartPtr<FileAttr> FileAttr::createFileAttrs()
{
    static SmartPtr<FileAttr> fileAttr(new FileAttr());
    fileAttr->md5 = new char[20];
    return fileAttr;
}

應用方法:

int main()
{
    SmartPtr<FileAttr> fa = FileAttr::createFileAttrs(); // 使用智能指針
    /* FileAttr *fa = FileAttr::createFileAttrs().get(); // 或者使用原始指針 */
    {
        memcpy(fa->md5, "md51", 4);
    }   
    {
        memcpy(fa->md5 + 4, "md52", 4);
    }
    cout << fa->md5<<endl;
    return 0;
}

打印輸出:

md51md52
destructor

由於自定義類未重載operator=,所以直接使用智能指針比較合適,需要原始指針的話調用get()函數即可。

C++ RCSP智能指針簡單實現與應用