我从 STL 中的代码分析这个问题:
自动 t(std::make_shared());
代码行构造一个shared_ptr;首先我们深入make_shared函数
// FUNCTION TEMPLATE make_shared
template<class _Ty,
class... _Types>
NODISCARD inline shared_ptr<_Ty> make_shared(_Types&&... _Args)
{ // make a shared_ptr
const auto _Rx = new _Ref_count_obj<_Ty>(_STD forward<_Types>(_Args)...);
shared_ptr<_Ty> _Ret;
_Ret._Set_ptr_rep_and_enable_shared(_Rx->_Getptr(), _Rx);
return (_Ret);
}
注意:我们深入了解函数_Ret.Set_ptr_rep_and_enable_shared。我们可以看到以下内容:
template<class _Ux>
void _Set_ptr_rep_and_enable_shared(_Ux * _Px, _Ref_count_base * _Rx)
{ // take ownership of _Px
this->_Set_ptr_rep(_Px, _Rx);
_Enable_shared_from_this(*this, _Px);
}
所以我们找到函数 _Enable_shared_from_this ,继续:
template<class _Other,
class _Yty>
void _Enable_shared_from_this(const shared_ptr<_Other>& _This, _Yty * _Ptr)
{ // possibly enable shared_from_this
_Enable_shared_from_this1(_This, _Ptr, _Conjunction_t<
negation<is_array<_Other>>,
negation<is_volatile<_Yty>>,
_Can_enable_shared<_Yty>>{});
}
我们找到一个关键点:_Can_enable_shared<_Yty>
template<class _Yty,
class = void>
struct _Can_enable_shared
: false_type
{ // detect unambiguous and accessible inheritance from enable_shared_from_this
};
template<class _Yty>
struct _Can_enable_shared<_Yty, void_t<typename _Yty::_Esft_type>>
: is_convertible<remove_cv_t<_Yty> *, typename _Yty::_Esft_type *>::type
{ // is_convertible is necessary to verify unambiguous inheritance
};
我们发现只有 _Yty 有 _Esft_type 并且 _Yty 可以转换为 _Esft_type,可以 _Yty 可以启用_shared(如果你想了解更多,那就是在 _Yty 中设置weak_ptr,否则你可能会在使用 shared_from_this 时遇到 bad_weak_ptr 错误)。那么_Esft_type 是什么?
template<class _Ty>
class enable_shared_from_this
{ // provide member functions that create shared_ptr to this
public:
using _Esft_type = enable_shared_from_this;
...
}
所以_Esft_type只是表示enable_shared_from_this<_Ty>,所以如果你使用private继承,外面不仅看不到_Esft_type而且_Yt不能转换成_Esft_type。所以weak_ptr 不能被设置,所以bad_weak_ptr 可能会被调用。
所以外部需要知道_Esft_type的存在,所以在构造shared_ptr时,也可以设置shared_test的weak_ptr。