为什么p可以输出正确调用父类析构函数呢?看源码
template<typename _Tp>//_Tp对应指定的 B 类型 class shared_ptr : public __shared_ptr<_Tp> //继承自__shared_ptr { ... //这里_Yp是传入指针的类型,也就是 C* template<typename _Yp, typename = _Constructible<_Yp*>> explicit shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { } //显示调用了父类的构造函数。 ... }; //__shared_ptr类 template<typename _Tp, _Lock_policy _Lp> //_Tp -> B class __shared_ptr : public __shared_ptr_access<_Tp, _Lp> { // 获取_Tp最本质的类型,去除[], 这里对应类型就是 B using element_type = typename remove_extent<_Tp>::type; ... template<typename _Yp, typename = _SafeConv<_Yp>> // _Yp -> C explicit __shared_ptr(_Yp* __p) : _M_ptr(__p), _M_refcount(__p, typename is_array<_Tp>::type()) //又将__p传给了引用计数对象 { static_assert( !is_void<_Yp>::value, "incomplete type" ); static_assert( sizeof(_Yp) > 0, "incomplete type" ); _M_enable_shared_from_this_with(__p); } ... //两个成员变量 element_type* _M_ptr; // 这里保存了B* 类型的指针 __shared_count<_Lp> _M_refcount; // 引用计数对象 }; // __shared_count 类,真正掌握__p的生杀大权 template<_Lock_policy _Lp> class __shared_count { public: constexpr __shared_count() noexcept : _M_pi(0) { } template<typename _Ptr> explicit __shared_count(_Ptr __p) : _M_pi(0) //2. 再调用这个 { __try { _M_pi = new _Sp_counted_ptr<_Ptr, _Lp>(__p); //用__p构建了_M_pi对象 } __catch(...) { delete __p; __throw_exception_again; } } template<typename _Ptr> __shared_count(_Ptr __p, /* is_array = */ false_type) //1.先调用这个 : __shared_count(__p) { } ... //成员变量 _Sp_counted_base<_Lp>* _M_pi; }; // _Sp_counted_ptr 类 template<typename _Ptr, _Lock_policy _Lp> class _Sp_counted_ptr final : public _Sp_counted_base<_Lp> { explicit _Sp_counted_ptr(_Ptr __p) noexcept : _M_ptr(__p) { } virtual void _M_dispose() noexcept { delete _M_ptr; } ... private: _Ptr _M_ptr; //看到这里,就明了了, 这是存储的C指针,所以在删除时 };看到这里,就比较明了, _Sp_counted_ptr存储的是C指针,所以在删除时,也是直接从子类调用析构函数的。
虽然在__shared_ptr中也保存了B的指针,目前猜测它是通过弱引用指向_Sp_counted_ptr中的C指针指向的实例的,并不会析构这个指针。(后续继续阅读源码研究一下。)
…未完待续
