enable_shared_from_this 中的空弱指针
Empty weak pointer in enable_shared_from_this
公开继承enable_shared_from_this并初始化class的对象后,在调用class的另一个函数时,我仍然可以看到enable_shared_from_this的空弱指针_ class 在 Visual Studio 中调试时。
所有存在的问题都是由于从 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();
编辑:
根据评论,问它是否正确,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>();
公开继承enable_shared_from_this并初始化class的对象后,在调用class的另一个函数时,我仍然可以看到enable_shared_from_this的空弱指针_ class 在 Visual Studio 中调试时。
所有存在的问题都是由于从 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();
编辑: 根据评论,问它是否正确,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>();