【问题标题】:Boost shared_from_this and destructor提升 shared_from_this 和析构函数
【发布时间】:2011-12-14 08:38:03
【问题描述】:

发现类的析构函数中不允许调用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_;
};

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

【问题讨论】:

  • 我想创建新标签:misuse-of-weak-ptr misunderstanding-of-enabled-shared-from-this

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


【解决方案1】:

如果您的经理对您的对象有一个shared_ptr,那么它就拥有它。 因此,您的对象不应被破坏,因为 Manager 仍然具有对它的引用。

你可以将一个弱指针传递给Manager,但是Manager的工作是检查指针是否仍然有效,如果不是则删除它。

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 根据设计,weak_ptr 用于让对象被销毁。所以它是对拥有weak_ptr 的对象来检查它的有效性。但无论如何都是好的解决方案。
    • 只是试图为您指出的一些错误的问题提供一些选项,因为我们不应该在我们的析构函数中从持有 shared_ptr 的东西中注销我们自己给我们。
    • 你好。 “一个你应该能够在析构函数中获得的weak_ptr”---你能解释一下,我怎样才能在析构函数中获得weak_ptr? enable_shared_from_this 仅包含 shared_from_this,不包含 weak_from_this...
    • @hate-engine C++17 终于支持weak_from_this了。
    • @rwols 你会如何使用它?
    【解决方案3】:

    这里我尝试将它翻译成共享指针。

    不要。

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

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

    weak_ptr 经常被误解为类指针类(其实不然,它是弱引用的东西)。

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

    enable_shared_from_this 更容易被误解。

    【讨论】:

      猜你喜欢
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-27
      • 2011-03-24
      • 2015-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多