【C++】智能指针之引用计数的实现

在C++11的标准中,引入了智能指针的概念。

相比于auto_ptr而言,其主要缺陷在于在进行指针拷贝的时候,会出现管理权转移的问题,导致原指针最终编成一个悬挂指针(dangling pointer)。

而智能指针shared_ptr, weak_ptr, 以及unique_ptr则各有侧重的解决相关的问题。具体可参考:

引入智能指针,不代表就不会出现问题。在使用不当的情况下,也会发生访问空指针等情况。

本文将简单的介绍,C++11中的智能指针的引用计数大致是如何实现的。部分内容节选自 C++ primer 5th。

首先,引用计数的工作方式如下:
  1. 除了初始化对象外,每个构造函数(拷贝构造函数除外)还要创建一个引用计数,用来记录与多少对象与正在创建的对象共享类型。当我们创建一个对象时,只有一个对象共享状态,因此将引用计数初始化为1
  2. 拷贝构造函数不分配新的计数器,而是拷贝构造函数给定的对象的数据成员,包括计数器。拷贝构造函数递增共享的计数器,指出给定的对象的状态又被一个新用户所共享 
  3. 析构函数递减计数器,指出共享状态的用户少了一个。如果计数器变为0,则析构函数释放状态。
  4. 拷贝赋值运算符递增右侧运算对象的计数器,递减左侧运算对象的计数器。如果左侧运算对象的计数器变为0,意味着他的共享状态没有用户,拷贝赋值运算符就必须销毁对象。
唯一的问题:确定在哪里存放引用计数。答案是:将计数器保存在动态内存中

以下程序,将引用计数的工作方式进行了完美的诠释:
#include <string>

class HasPtr {
public:
    // constructor allocates a new string and a new counter, which it sets to 1
    HasPtr(const std::string &s = new std::string()) :
        ps(new std::string(s)), i(0), use(new std::size_t (1)) {}
    // copy constructor copies all three data members and increments the counter
    HasPtr(const HasPtr &p) :
        ps(p.ps), i(p.i), use(p.use) { ++ *use; }
    HasPtr& operator= (const HasPtr& rhs) {
        // increment the use count of the right-hand operand
        ++*rhs.use;  
        if(--*use == 0) {   // then decrement this object’s counter
            delete ps;      // if no other users
            delete use;     // free this object’s allocated members
        }
        ps = rhs.ps;        // copy data from rhs into this object
        i = rhs.i;
        use = rhs.use;
        return *this;       // return this object
    }
    ~HasPtr() {
        if(--*use == 0) {  // if the reference count goes to 0
            delete ps;     // delete the string
            delete use;    // and the counter
        }
    }

private:
    std::string *ps;
    int i;
    // member to keep track of how many objects share *ps
    size_t *use;  // --> reference counter

};



  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值