zoukankan      html  css  js  c++  java
  • C++ RCSP智能指针简单实现与应用

    智能指针的实现代码来源博客:《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()函数即可。

    种树最好的时间是十年前,其次是现在。
  • 相关阅读:
    npx小工具
    2015 Multi-University Training Contest 1
    字符串 --- KMP Eentend-Kmp 自动机 trie图 trie树 后缀树 后缀数组
    AC自动机
    AC自动机
    区间合并 --- Codeforces 558D : Gess Your Way Out ! II
    暴力 + 贪心 --- Codeforces 558C : Amr and Chemistry
    计数排序 + 线段树优化 --- Codeforces 558E : A Simple Task
    Ubuntu 16.04 安装mysql并设置远程访问
    数学 --- 高斯消元 POJ 1830
  • 原文地址:https://www.cnblogs.com/bobojiang/p/8580015.html
Copyright © 2011-2022 走看看