【问题标题】:Empty weak pointer in enable_shared_from_thisenable_shared_from_this 中的空弱指针
【发布时间】:2019-05-11 21:44:37
【问题描述】:

在公开继承 enable_shared_from_this 并初始化类的对象后,在调用该类的另一个函数时,我在 Visual Studio 中调试时仍然可以看到 enable_shared_from_this_class 的空弱指针。

所有现有问题都是由于私下继承自 enable_shared_from_this 或在构造函数中调用 weak_from_this。这不是我的情况。我目前正在使用 c++ catch 框架在 Visual Studio 调试器中测试这个场景。在 Initialize 函数中,我可以看到,这个对象的 weak_ptr 是空的。

头文件:


template <typename T>
class IInfo
public:
IInfo()
    {}
    virtual ~IInfo()
    {}
    virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T>) = 0;
};

template <typename T>
class Info : public IInfo<T>, public std::enable_shared_from_this<Info<T>>
{
public:
    Info() {}
    ~Info() {}
    virtual bool RegisterForChange(FUNC_PTR<T> Callback, std::weak_ptr<T> callerContext) override
    {
        //Some code
        _callerContext = callerContext;
    }
private:
    std::weak_ptr<T> _callerContext;
};


class Env : public std::enable_shared_from_this<Env>
{
public:
    Env();
    bool Initialize();
    static void func(/ some arguments / );
private:
    std::shared_ptr<Info<Env>>_spInfo;
    //other variables
}

Cpp 文件:

Env::Env() : _spInfo() // + other variables in initializer list
{
    _spInfo = std::make_shared<Info<Env>>();
}

bool Env::Initialize()
{
    _spInfo->RegisterForChange(FUNC_PTR<Env>func, this->weak_from_this());
}

测试用例:(使用 cpp catch 框架)

Env env;
env.Initialize();

编辑: 根据 cmets ,要求正确,Env 模块将由一个插件管理,该插件将创建一个 unique_ptr 并调用 Initialize。 比如:

    template<typename T>
    std::unique_ptr<T> BringUp()
    {
        std::unique_ptr<T> ptr(std::make_unique<T>());
        if (ptr && ptr->Initialize())
            return std::move(ptr);
    }

std::unique_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();

我仍然面临同样的问题。 在这种情况下我应该如何管理 Env?

【问题讨论】:

  • 不清楚您对这段代码的期望。 std::enable_shared_from_this 用于由 shared_ptr 管理的对象,env 不是由我的智能指针管理的
  • ^^^^ Env env; 这就是一个问题。你的类不能仅仅继承自std::enable_shared_from_this。它实际上必须被创建 并作为std::shared_ptr&lt;Env&gt; 进行管理。例如:auto env = std::make_shared&lt;Env&gt;(); env-&gt;Initialize();
  • 我已将数据附加到我的问题中以便正确提问。

标签: c++ shared-ptr unique-ptr weak-ptr enable-shared-from-this


【解决方案1】:

您的构造代码仍然是错误的。要使shared_from_this 工作,对象的生命周期必须由共享指针管理。首先,您尝试按范围管理它,然后尝试使用唯一指针管理它。这些都不行。

shared_from_this 的要点是允许对象的生命周期通过需要扩展它的代码来扩展。为此,对象的生命周期必须由某种结构来管理,使对象能够延长其生命周期。作用域不能这样做,因为当作用域结束时,对象的内存就会被释放。 unique_ptr 不能这样做,因为任何时候都只能存在一个指向该对象的指针,因此无法延长它的寿命,因为这需要两个指针(一个必须已经存在,否则它会死掉,而一个延长它的寿命将是另一个)。

使用std::make_shared 构造Env 对象并将std::shared_ptr 存储到其中。

    template<typename T>
    std::shared_ptr<T> BringUp()
    {
        std::shared_ptr<T> ptr(std::make_shared<T>());
        if (ptr && ptr->Initialize())
            return std::move(ptr);
    }

std::shared_ptr<Env> _envPtr;
_envPtr = BringUp<Env>();

【讨论】:

  • 感谢您的详细解释。我发现了一个问题link 人们试图创建一个黑客,但我不确定这是否是正确的方法。
  • 你可以破解它,这样你就有一个带有空删除器的shared_ptr。但共享指针的全部意义在于允许延长对象的生命周期,而这会破坏这一点。
猜你喜欢
  • 2011-05-28
  • 1970-01-01
  • 2011-10-13
  • 1970-01-01
  • 2012-01-11
  • 2013-03-07
  • 2014-05-13
  • 2014-08-16
  • 2011-06-03
相关资源
最近更新 更多