【问题标题】:enable_shared_from_this (c++0x): what am I doing wrong?enable_shared_from_this (c++0x):我做错了什么?
【发布时间】:2010-12-13 10:48:38
【问题描述】:

我只是在玩弄即将推出的新 c++ 标准中的智能指针。但是我无法掌握 shared_from_this 函数的用法。这是我所拥有的:

#include <iostream>
#include <memory>

class CVerboseBornAndDie2 : public std::enable_shared_from_this<CVerboseBornAndDie2>
{
public:
    std::string m_Name;
    CVerboseBornAndDie2(std::string name) : m_Name(name)
    {
        std::cout << m_Name << " (" <<  this << ") is born!" << std::endl;
    }
    virtual ~CVerboseBornAndDie2()
    {
        std::cout << m_Name << " (" <<  this << ") is dying!" << std::endl;
    }
};

int main(){
    CVerboseBornAndDie2* vbad = new CVerboseBornAndDie2("foo");
    std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this();
}

它会在该行中抛出一个 std::bad_weak_ptr 异常

std::shared_ptr<CVerboseBornAndDie2> p = vbad->shared_from_this();

如果我这样做

std::shared_ptr<CVerboseBornAndDie2> p(vbad);

它有效,然后我可以做

std::shared_ptr<CVerboseBornAndDie2> p2 = p.get()->shared_from_this();

所以在我可以使用 shared_from_this 之前,该对象必须属于一个 shared_ptr 吗?但是我怎么能事先知道呢?

【问题讨论】:

    标签: c++ c++11 shared-ptr smart-pointers


    【解决方案1】:

    使用shared_from_this 的前提条件是必须至少存在一个拥有相关对象的shared_ptr。这意味着您只能使用shared_from_this 检索拥有您有引用或指针的对象的shared_ptr,您不能使用它来确定此类对象是否由shared_ptr 拥有。

    您需要重新设计您的设计,以便保证任何此类对象都由shared_ptr 管理,或者您永远不需要知道,或者最终(最不希望)创建一些其他方式管理这些知识。

    【讨论】:

    • 如果您想查明对象是否由 shared_ptr 持有,难道您不能在对 shared_from_this 的调用周围放置一个 try-block 吗?我不知道(即将推出的)标准中如何指定它,但它似乎不是未定义的行为——它正在引发异常。
    • @nobar:这在推理上是不安全的。您将依赖未记录的实现细节。 shared_from_this 不是测试对象是否为共享指针所有的方法;它是一种从您知道由共享指针拥有的对象检索共享指针的方法。
    • 我认为你是对的。 C++0x 草案说“应至少有一个 shared_ptr 实例 p 拥有 &t。”,但它没有说明否则会发生什么。它根据weak_ptr 显示了一个实现(这意味着将在错误时引发异常),但这只是一个“建议”。我想知道最终是否会更好地指定错误处理。
    【解决方案2】:

    为了扩展 Charles 的回答,当您使用 enable_shared_from_this 时,您通常需要如下所示的内容,以确保存在 shared_ptr。

    class my_class : public std::enable_shared_from_this<my_class>
    {
    public:
        static std::shared_ptr<my_class> create() // can only be created as shared_ptr
        {
             return std::shared_ptr<my_class>(new my_class());
        }
    private
        my_class(){} // don't allow non shared_ptr instances.
    };
    

    【讨论】:

    • create() 应该是static,不是吗?
    • 要默认共享,您可以使用以下内容:try { return shared_from_this(); } catch (const bad_weak_ptr&amp;) { return make_shared&lt;C&gt;(); }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    相关资源
    最近更新 更多