美文网首页C++ 2a
std::enable_shared_from_this的用法

std::enable_shared_from_this的用法

作者: 左图右码 | 来源:发表于2022-06-22 18:34 被阅读0次

    有些类的成员函数需要获得自身的std::shared_ptr,但不能就地从this创建,这样会导致多个毫无关系的智能指针引用到同一个对象,导致重复释放【不能传递share_ptr<this>,因为这样会造成2个以上非共享的share_ptr指向同一个对象,未增加引用计数导对象被析构两次】。
    std::enable_shared_from_this<>模版类就是解决这个问题。
    请看regTo的实现,就需要使用本身的智能指针。

    class base : public std::enable_shared_from_this<base>
    {
        std::string msg;
    public:
        base(std::string s) : msg(s){}
        virtual ~base() = default;
        virtual void print()
        {
            std::cout << msg << std::endl;
        }
        void regTo(class regObj*);
    };
    
    class regObj
    {
        std::vector<std::shared_ptr<base>> objs;
    public:
        void regobject(std::shared_ptr<base> shp)
        {
            objs.push_back(shp);
        }
        void print()
        {
            for (auto& c : objs)
                c->print();
        }
    };
    
    void base::regTo(class regObj* p)
    {
        p->regobject(this->shared_from_this());
    }
    
    class concrete1 : public base
    {
    public:
        concrete1(const char* msg) : base(msg){}
    };
    
    class concrete2 : public base
    {
    public:
        concrete2(const char* msg) : base(msg) {}
    };
    
    
    int main(int,const char**)
    {
        auto instance = new regObj;
        auto p1 = std::make_shared<concrete1>("concreteObj1");
        std::shared_ptr<concreate2> p2(new concrete2("concreteObj2"));
        p1->regTo(instance);
        p2->regTo(instance);
        instance->print();
        delete instance;
    }
    

    上面regTo函数就需要获得本身的shared_ptr。
    注意:调用这个函数的实例必须是构建在shared_ptr上的。因为shared_from_this是从一个weak_ptr构建的一个shared_ptr,这里的weak_ptr是一个shared_ptr弱引用。如果本身没有构建,自然弱引用也是空的。

    如果如下所示的使用,则会发生运行时错误:

    auto ptr = new concrete2("concreteObj3");
    ptr->regTo(instance);
    

    抛出异常的位置在这里:

        template<class _Ty2,
        enable_if_t<_SP_pointer_compatible<_Ty2, _Ty>::value, int> = 0>
        explicit shared_ptr(const weak_ptr<_Ty2>& _Other)
        {   // construct shared_ptr object that owns resource *_Other
          if (!this->_Construct_from_weak(_Other))
            {
              _THROW(bad_weak_ptr{});
            }
        }
    

    相关文章

      网友评论

        本文标题:std::enable_shared_from_this的用法

        本文链接:https://www.haomeiwen.com/subject/ejuuvrtx.html