参考:
https://stackoverflow.com/questions/712279/what-is-the-usefulness-of-enable-shared-from-this
#include <memory>
using namespace std;
class Y : public enable_shared_from_this<Y>
{
public:
shared_ptr<Y> f()
{
return shared_from_this();
}
int iData = 0x12345678;
};
#include <cassert>
int main()
{
Y* data = new Y();
shared_ptr<Y> p(data);
shared_ptr<Y> q = p->f();
assert(p == q);
assert(!(p < q || q < p)); // p and q must share ownership
std::cout << "[hello]" << std::endl;
return 0;
}
template <class _Ux>
void _Set_ptr_rep_and_enable_shared(_Ux* const _Px, _Ref_count_base* const _Rx) noexcept { // take ownership of _Px
this->_Ptr = _Px;
this->_Rep = _Rx;
#if _HAS_IF_CONSTEXPR
if constexpr (conjunction_v<negation<is_array<_Ty>>, negation<is_volatile<_Ux>>, _Can_enable_shared<_Ux>>) {
if (_Px && _Px->_Wptr.expired()) {// 直接取的_Ux类型中的_Wptr
_Px->_Wptr = shared_ptr<remove_cv_t<_Ux>>(*this, const_cast<remove_cv_t<_Ux>*>(_Px));
}
}
#else // ^^^ _HAS_IF_CONSTEXPR // !_HAS_IF_CONSTEXPR vvv
_Enable_shared_from_this1(*this, _Px,
bool_constant<
conjunction_v<negation<is_array<_Ty>>, negation<is_volatile<_Ux>>, _Can_enable_shared<_Ux>>>{});
#endif // _HAS_IF_CONSTEXPR
}
再看 enable_shared_from_this 的实现
// CLASS TEMPLATE enable_shared_from_this
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;
_NODISCARD shared_ptr<_Ty> shared_from_this() {
return shared_ptr<_Ty>(_Wptr);
}
_NODISCARD shared_ptr<const _Ty> shared_from_this() const {
return shared_ptr<const _Ty>(_Wptr);
}
_NODISCARD weak_ptr<_Ty> weak_from_this() noexcept {
return _Wptr;
}
_NODISCARD weak_ptr<const _Ty> weak_from_this() const noexcept {
return _Wptr;
}
protected:
constexpr enable_shared_from_this() noexcept : _Wptr() {}
enable_shared_from_this(const enable_shared_from_this&) noexcept : _Wptr() {
// construct (must value-initialize _Wptr)
}
enable_shared_from_this& operator=(const enable_shared_from_this&) noexcept { // assign (must not change _Wptr)
return *this;
}
~enable_shared_from_this() = default;
private:
#if _HAS_IF_CONSTEXPR
template <class _Yty>
friend class shared_ptr;
#else // ^^^ _HAS_IF_CONSTEXPR // !_HAS_IF_CONSTEXPR vvv
template <class _Other, class _Yty>
friend void _Enable_shared_from_this1(const shared_ptr<_Other>& _This, _Yty* _Ptr, true_type) noexcept;
#endif // _HAS_IF_CONSTEXPR
mutable weak_ptr<_Ty> _Wptr;
};
从 enable_shared_from_this 继承之后,本类的第一个成员,成了 mutable weak_ptr<_Ty> _Wptr;,然后,在shared_ptr代码里面,识别到这个类型之后,将对其进行赋值
观察shared_from_this 可以看到相关的引用。
这种实现就相当于,将本来
[智能指针—>指向所管理的对象]
转换成了
[智能指针+所管理的对象]