前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ RCSP智能指针简单实现与应用

C++ RCSP智能指针简单实现与应用

作者头像
jianghaibobo
发布2019-08-02 16:28:56
5530
发布2019-08-02 16:28:56
举报
文章被收录于专栏:我命由我不由天

智能指针的实现代码来源博客:《http://blog.csdn.net/to_be_better/article/details/53570910》

修改:添加 get()函数,用以获得原始指针(raw pointer)。

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

智能指针的实现代码如下:

代码语言:javascript
复制
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类:

代码语言:javascript
复制
class Uncopyable
{
  protected:
    Uncopyable() {}
    ~Uncopyable() {}

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

一个应用例子:

目的是创建一个类的智能指针,用以描述文件的一些属性的类,在后续代码中使用这个指针来赋予或读取这些属性。当然,使用智能指针为了防止资源泄漏,符合本文初衷。

由成员函数:createFileAttrs() 产生动态创建一个静态的智能指针,由这个指针去给类中的成员变量分配资源,并返回这个指针,即可实现功能。

测试类:

代码语言:javascript
复制
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;
}

应用方法:

代码语言:javascript
复制
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()函数即可。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-03-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档