libstdc++ enable_shared_from_this 源码分析

继承 std::enable_shared_from_this 模板类之后就多了一个弱指针(_M_weak_this)。同时还多了一个 __enable_shared_from_this_base 方法,创建共享指针时该方法能被 ADL 找到,以关联和共享控制块。该方法是私有的,不过 __shared_ptr<typename, typename> 是友元类,因此能访问它。

共享指针模板类 __shared_ptr 有个私有方法 _M_enable_shared_from_this_with,它能通过 SFINAE 判断元素类型是否是继承自 enable_shared_from_this 的 CRTP 类,如果是则将自己的控制块关联给 enable_shared_from_this 中的弱指针。

按照这个逻辑,在创建共享指针的时候,_M_enable_shared_from_this_with 应该会被调用。这一点确实可以被验证(下面还有一些构造函数,就不展示了):

std::make_shared 会将元素和控制块放在一起,减少内存申请的次数,那么它会对 enable_shared_from_this 进行特殊判断吗?从 libstdc++ 源码来看是不会的,这个函数通过特殊的 tag 直接调用了一个私有的 shared_ptr 构造函数,该构造函数包含了对 _M_enable_shared_from_this_with 的调用。

Note

使用 make_shared 时 allocator 是不能被指定的。