c++ - enable_shared_from_this 中的空弱指针

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

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

所有存在的问题都是由于从 enable_shared_from_this 私有(private)继承或在构造函数中调用 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();

编辑: 根据评论,要求正确,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?

最佳答案

你的构造代码还是错的。要使 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>();

关于c++ - enable_shared_from_this 中的空弱指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56094494/

相关文章:

c++ - 在没有 RValue 隐式转换的情况下正确实现

c++ - std::unique_ptr 和 std::shared_ptr 作为虚函数的参数

c++ - 使用两个 uint_32 数的倍数时模幂运算溢出

c++ - 对 boost::asio::io_context::run() 和 boost::thread::join() 感到困惑

c++ - 未在函数结果上调用复制构造函数

c++ - unique_ptr 链表的堆栈溢出

c++ - unique_ptr,你引用了一个已删除的函数

c++ - 需要链表解释

c++ - shared_ptr<Base> 和派生类的对象

c++ - 什么时候使用虚拟析构函数?