[英]'std::bad_weak_ptr' error while using shared_from_this
注意:在發布問題之前,我在使用shared_from_this
將現有 shared_ptr 實例的 shared_ptr 傳遞給另一個方法時,已經完成了關於 std::bad_weak_error 的現有問題。 它們都不像這樣:
shared_from_this()
之前,已經創建了 class 的現有 shared_ptr 實例以下是重現錯誤的示例代碼:
#include <iostream>
#include <memory>
class ILogger {
public:
virtual ~ILogger() {}
virtual void Log() = 0;
};
class LogManager;
class Logger : public ILogger {
public:
Logger(std::shared_ptr<LogManager> logManager)
: m_logManager(logManager)
{
}
void Log() override
{
std::cout << "Dump logs";
}
private:
std::shared_ptr<LogManager> m_logManager;
};
class ILogManager {
public:
virtual ~ILogManager() {}
virtual std::shared_ptr<ILogger> GetLogger() = 0;
};
class LogManager : public ILogManager, public std::enable_shared_from_this<LogManager> {
public:
virtual std::shared_ptr<ILogger> GetLogger()
{
return std::static_pointer_cast<ILogger>(std::make_shared<Logger>(this->shared_from_this()));
}
};
class LogManagerFactory {
public:
static ILogManager* Create()
{
auto logManager = new LogManager();
return logManager;
}
};
int main()
{
auto logManager = std::shared_ptr<ILogManager>(LogManagerFactory::Create());
auto logger = logManager->GetLogger();
}
錯誤:
Program returned: 139
terminate called after throwing an instance of 'std::bad_weak_ptr'
what(): bad_weak_ptr
為了初始化enable_shared_from_this
子對象, shared_ptr
構造函數需要知道所討論的 class 繼承自enable_shared_from_this
。 查看創建共享指針的表達式:
std::shared_ptr<ILogManager>(LogManagerFactory::Create());
該表達式中唯一涉及的 class並未繼承自std::enable_shared_from_this<>
。 您正在從指向ILogManager
的指針創建指向ILogManager
的共享指針。 這就是編譯器生成代碼的目的——為不從enable_shared_from_this
繼承的 class 創建一個shared_ptr
。 構造函數不知道您期望它初始化enable_shared_from_this
子對象。
如果您將LogManagerFactory::Create()
的返回類型從ILogManager*
更改為LogManager*
,則該代碼有效。 只要構造參數將LogManager
引入圖片,您就可以保留std::shared_ptr<ILogManager>
部分。
注意:為了更安全, LogManagerFactory::Create()
應該返回unique_ptr
或shared_ptr
而不是原始指針,以清楚地表明調用者獲得了所有權。
當你運行時:
std::shared_ptr<ILogManager>(LogManagerFactory::Create())
shared_ptr
只知道指針是一個沒有ILogManager
的enable_shared_from_this
,所以不設置弱指針。
解決方案(通常是更安全的代碼)是在Create
中創建shared_ptr
,此時構造函數可以看到真實類型,因此enable_shared_from_this
將起作用:
static std::shared_ptr<ILogManager> Create()
{
auto logManager = new LogManager();
return std::shared_ptr<ILogManager>(logManager);
}
或者更簡單地說:
static std::shared_ptr<ILogManager> Create()
{
return std::make_shared<LogManager>();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.