2020-08-20

C++11的智能指针是继可变模板参数,右值引用与移动语义以后又一个非常强大的特性。由于C++是没有GC的语言,程序员需要自己去管理堆上分配的内存。智能指针在我的理解看来实现了部分GC的功能,本质还是使用的引用计数。当RC变到0的时候自动释放相关内存。本质是对一个裸指针进行了封装加上了引用计数罢了。智能指针有四种(其实C++11引入的是三种)unique_ptr shared_ptr weak_ptr和基本被废弃的auto_ptr。下面就针对不同种类的智能指针展开记录。// TODO enable_shared_from_this

unique_ptr

顾名思义对象是unique的,同一时间只有一个智能指针持有对应的对象。因此unique_ptr delete了赋值与拷贝构造,只有移动构造。unique_ptr生命周期结束后就会调用里面裸指针指向的对象的deleter,默认是析构函数,也可以在创建unique_ptr的时候指定你想要的deleter。

shared_ptr

也是顾名思义,可以有多个shared_ptr指向同一个对象,只有在shared_ptr的RC为0的时候才会调用deleter。可以复制和拷贝。会对应的改变RC的值。

weak_ptr

这个指针存在的意义主要是为了解决两个对象互相持有对方的shared_ptr形成循环引用带来的内存泄漏 (A 持有 B的shared_ptr, B 持有 A的shared_ptr, RC永远不为0)。当使用weak_ptr的时候不会增加shared_ptr的RC,增加的是weak_ptr 的weak_RC。与unique_ptr和shared_ptr不同的是weak_ptr是不支持解引用的(因为指向的对象可能已经不存在了),需要调用lock方法返回对应的shared_ptr,如果shared_ptr不为空说明对象仍然存在才可以使用指向的对象。

鉴于现在有些公司面试还要手写智能指针,这里就研究一下智能指针的源码写一个demo出来。在这里我们写一个shared_ptr的demo。

首先我们先研究一下C++标准里咋写的这个玩意儿。这里截图用的xcode的llvm的libc++。

我们先看一下标准库里的shared_ptr到底存了啥。看一下他的成员变量。

主要是两个,第一个是智能指针包的裸指针,第二个是指向存储strong RC和weak RC值的一个结构体。再看看那个记录了RC的结构体里到底放了啥。

其实里面存的就是一个shared_ptr的strong ref和weak ref。有一点值得注意的是我们看源码可以看到里面对strong和weak的引用计数都是atomic的。因此在引用计数这个方面智能指针是线程安全的。但是你操作指针指向的对象的时候不是线程安全的哦。(待续)

现在我们知道了libc++中智能指针的实现方式。回想一下智能指针的需求我们实现起来大概就有思路了。首先持有一个裸指针和一个记录RC的结构体指针。在赋值和析构的时候对RC结构体里的数据进行修改即可。(待续)

你可能感兴趣的:(2020-08-20)