自定义实现c++中std::enable_shared_from_this功能

主要概念

std::enable_shared_from_this,能通过其shared_from_this()函数获得当前shared_ptr的副本,指向原指针对象一样,此副本析构的时候不会导致二次析构(如果直接用std::shared_tr(this), 就会有这个问题),因为有了副本,所以就不会有直接使用原本shared_ptr带来的循环引用问题。

一般会这样用:

class NodeBase : public enable_shared_from_this
{
public:
    NodeBase()
    {
        std::cout << "NodeBase::constructor()...\n";
    }
    [[nodiscard]] std::shared_ptr getptr()
    {
        return shared_from_this();
    }
    virtual ~NodeBase()
    {
        std::cout << "NodeBase::destructor()...\n";
    }
};
void testMain()
{
    std::shared_ptr p0 = std::make_shared();
    std::shared_ptr q0 = p0->getptr();
    std::cout << "(p0 == q0): " << (p0.get() == q0.get()) << std::endl;
    std::cout << p0.use_count() << std::endl;
    std::cout << q0.use_count() << std::endl;
}

如果将std::enable_shared_from_this用于更复杂的类模板中,则会不方便,这时候就需要用实现原理自己实现相关功能。先简单看一下源码:

enable_shared_from_this是一个基类,在MSVC中enable_shared_from_this功能实现依赖的两个关键模板函数, 位于:

Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include\memory文件中的template
class shared_ptr : public _Ptr_base<_Ty> {}

定义中。

Linux GCC 请参见: gcc\libstdc++-v3\include\bits\shared_ptr_base.h

也就是说enable_shared_from_this实际上是基于std::shared_ptr的扩展

// 构造的时候调用
template 
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 constexpr (conjunction_v>, negation>, _Can_enable_shared<_Ux>>)
    {
        if (_Px && _Px->_Wptr.expired())
        {
            _Px->_Wptr = shared_ptr>(*this, const_cast*>(_Px));
        }
    }
}
// 析构的时候调用
void _Set_ptr_rep_and_enable_shared(nullptr_t, _Ref_count_base* const _Rx) noexcept
{ // take ownership of nullptr
    this->_Ptr = nullptr;
    this->_Rep = _Rx;
}

由此可简洁的自定义一个enable_shared_from_this_t类来happy一下,代码如下:

template 
class enable_shared_from_this_t
{
public:
    // 下面这一句是关键代码
    using _Esft_type = enable_shared_from_this_t;
    _NODISCARD std::shared_ptr<_Ty> shared_from_this()
    {
        return std::shared_ptr<_Ty>(_Wptr);
    }
protected:
    constexpr enable_shared_from_this_t() noexcept
    {
    }
    ~enable_shared_from_this_t() = default;

private:
    template 
    friend class std::shared_ptr;
    // _Wptr变量名不可变
    mutable std::weak_ptr<_Ty> _Wptr;
};

自定义实现

如何自定义实现 std::enable_shared_from_this才具有的返回shared_ptr副本功能呢?,直接上代码(MSVC)吧:

class BigUnit
{
public:
    using _Esft_type = BigUnit;
    BigUnit()
    {
        std::cout << "BigUnit::constructor()...\n";
    }
    [[nodiscard]] std::shared_ptr getSharedPtr()
    {
        return std::shared_ptr(_Wptr);
    }
    [[nodiscard]] std::shared_ptr getSharedPtr() const
    {
        return std::shared_ptr(_Wptr);
    }

    virtual ~BigUnit()
    {
        std::cout << "BigUnit::destructor()...\n";
    }

private:
    template 
    friend class std::shared_ptr;

    mutable std::weak_ptr _Wptr;
};

好了,可以用了。如果还要更高级的功能,自己扩展实现一个shared_ptr。。。

你可能感兴趣的:(c++/c/asm,c++)