前言
感觉好久没看stl了,中间跑去看图形学入门了,图形学是真的有趣,但是也是真难,不过接着补坑,把unique_ptr的好兄弟shared_ptr也看了。
STL版本
本文所使用的stl版本为libc++ 13.0,属于LLVM项目。
如果遇到不熟悉的宏定义可以参考文档Symbol Visibility Macros
Shared_ptr
应该算是c++中的老熟人,应该绝大部分人应该使用过,或者在面试中见过它,对它的引用计数器印象深刻吧。这次我们看看stl的源码中shared_ptr是怎么实现的。
定义,构造和赋值
定义和关键成员
template<class _Tp>
class _LIBCPP_SHARED_PTR_TRIVIAL_ABI _LIBCPP_TEMPLATE_VIS shared_ptr
{
public:
#if _LIBCPP_STD_VER > 14
typedef weak_ptr<_Tp> weak_type;
typedef remove_extent_t<_Tp> element_type;
#else
typedef _Tp element_type;
#endif
private:
element_type* __ptr_;
__shared_weak_count* __cntrl_;
struct __nat {
int __for_bool_;};
}
shared_ptr内部有两个比较关键的成员类型,一个是ptr,另一个是__shared_weak_count,前着存储指针,后者存储计数器,在两个源码我们等看完构造和拷贝构造函数再看吧。
__nat是用来和enable_if配合,检测自定义析构函数,但是有点疑惑为什么不在template定义位置做,而要在参数位置做,在c++11后已经支持模板函数的默认模板参数。也搜索不到有用的资料,这点等以后来验证吧。
构造函数
先看一个最简单的构造函数,是参数为原始指针的构造
template<class _Yp, class = _EnableIf<
_And<
__compatible_with<_Yp, _Tp>
// In C++03 we get errors when trying to do SFINAE with the
// delete operator, so we always pretend that it's deletable.
// The same happens on GCC.
#if !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_COMPILER_GCC)
, _If<is_array<_Tp>::value, __is_array_deletable<_Yp*>,<