Boost shared_from_this and destructor

眉间皱痕 提交于 2020-01-12 10:08:46

问题


I found that it is not allowed to call shared_from_this in the destructor from a class:

https://svn.boost.org/trac/boost/ticket/147

This behavior is by design. Since the destructor will destroy the object, it is not safe to create a shared_ptr to it as it will become dangling once the destructor ends.

I understand the argument, but what if I need a "shared_from_this" pointer for cleaning up references ( not for sharing owner ship).

Here is an example where I'm not using shared_ptr:

class A{
public:
    A( Manager * m ) : m_(m) {
        m_->add(this);
    }

    ~A() {
        m_->remove(this);
    }

private:
    Manager * m_;
};

Here I have tried to translate it into shared pointers. But I can not find a good way to finish the destructor:

class A : public boost::enable_shared_from_this< A > {
public:
    typedef boost::shared_ptr< A > Ptr;

    static Ptr create( Manager * m ) {
        Ptr p( new A(m));
        p->init();
        return p;
    }

    ~A() {
        // NON-WORKING
        // m_->remove( shared_from_this() );
    }

private:
    A( Manager * m ) : m_(m) { }

    void init() {
        m_->add(shared_from_this());
    }

    Manager * m_;
};

How can I implement the destructor in the example above?


回答1:


If your Manager has a shared_ptr to your object, then it owns it. Thus your object shall not be destructed, as the Manager still have a reference to it.

You may pass a weak pointer to the Manager, but then it's the work of the manager to check that the pointer is still valid, and delete it if not.

Your question is interesting, but your case is caused by a misconception. As long as an object own a reference to your object, it's the aim of shared_ptr that it will not be destructed. For the destructor to be called, you should have manually called delete on the pointer, which is a bad behavior when working with shared_ptr.

Simple define who really own the object, and give them the shared_ptr. If a part of code occasionally need your object - if it exists - then give it a weak_ptr.




回答2:


If the Manager instance has a shared_ptr to your class, your class will never be destroyed until that shared_ptr is gone. I assume, therefore, that Manager is actually storing a weak_ptr to your instance, in which case Manager's API should probably accept a weak_ptr which you should be able to get in the destructor. If you can't, just make one in your constructor and store it for later.




回答3:


Here I have tried to translate it into shared pointers.

Don't.

Your first class is fine (except that it is an implicitly declared copy constructor and copy assignment - unrelated with the use of raw pointers).

Why bother with smart pointers? because it's fashionable?

weak_ptr is often misunderstood as a pointer-like class (it is not, it is a weak reference thing).

weak_ptr is rarely appropriate. (Even with Boost documentation spreads confusion about when weak_ptr is appropriate.)

enable_shared_from_this is even easier to misunderstand.



来源:https://stackoverflow.com/questions/8501503/boost-shared-from-this-and-destructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!