提升shared_from_this和析构函数

时间:2011-12-14 08:38:03

标签: c++ boost shared-ptr object-lifetime weak-ptr

我发现不允许在类的析构函数中调用shared_from_this:

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

  

此行为是设计使然。由于析构函数会破坏对象,因此创建一个shared_ptr是不安全的,因为一旦析构函数结束它就会变成悬空。

我理解这个论点,但是如果我需要一个“shared_from_this”指针来清理引用(不是为了共享所有者的船只),那该怎么办。

以下是我不使用shared_ptr的示例:

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

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

private:
    Manager * m_;
};

在这里,我试图将其转换为共享指针。但我找不到完成析构函数的好方法:

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_;
};

如何在上面的例子中实现析构函数?

3 个答案:

答案 0 :(得分:4)

如果您的管理员对您的对象有shared_ptr,那么它拥有它。 因此,您的对象不应被破坏,因为经理仍然可以参考它。

您可以将弱指针传递给Manager,但是管理器的工作是检查指针是否仍然有效,如果没有则删除它。

您的问题很有意思,但您的案例是由误解造成的。只要一个对象拥有对象的引用,shared_ptr的目的就是它不会被破坏。对于要调用的析构函数,您应该在指针上手动调用delete,这在使用shared_ptr时是不好的行为。

简单定义谁真正拥有该对象,并为他们提供shared_ptr。如果代码的一部分偶尔需要你的对象 - 如果它存在 - 那么给它一个weak_ptr。

答案 1 :(得分:3)

如果Manager实例的类具有shared_ptr,那么在shared_ptr消失之前,您的类将永远不会被销毁。因此,我假设Manager实际上是在你的实例中存储了一个weak_ptr,在这种情况下,Manager的API应该接受一个你应该能够在析构函数中获得的weak_ptr。如果你不能,只需在构造函数中创建一个并存储它以供日后使用。

答案 2 :(得分:1)

  

在这里,我试图将其转换为共享指针。

别。

你的第一个类很好(除了它是一个隐式声明的复制构造函数和复制赋值 - 与使用原始指针无关)。

为什么要使用智能指针呢?因为它很时髦?

weak_ptr经常被误解为类似指针的类(它不是,它是一个弱引用的东西)。

weak_ptr很少适合。 (即使使用Boost文档,也会对weak_ptr何时合适产生混淆。)

enable_shared_from_this更容易误解。