使用shared_from_this时出现“std::bad_weak_ptr”错误

Lal*_*sin 0 c++ shared-ptr weak-ptr c++11 enable-shared-from-this

注意:在发布问题之前,我已经浏览了有关std::bad_weak_errorwhile usingshared_from_this将现有实例的 shared_ptr 传递shared_ptr给另一个方法的现有问题。它们都与此类似:

  • 在尝试调用之前已经创建了该类的现有共享指针实例shared_from_this()
  • 该类继承自std::enable_shared_from_this<>public。

以下是重现该错误的示例代码:


#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();
}
Run Code Online (Sandbox Code Playgroud)

错误:

Program returned: 139
terminate called after throwing an instance of 'std::bad_weak_ptr'
  what():  bad_weak_ptr
Run Code Online (Sandbox Code Playgroud)

代码链接: https: //godbolt.org/z/GTcafM449

JaM*_*MiT 7

为了enable_shared_from_this初始化子对象,shared_ptr构造函数需要知道相关类继承自enable_shared_from_this. 查看创建共享指针的表达式:

\n
\n

std::shared_ptr<ILogManager>(LogManagerFactory::Create());

\n
\n

该表达式中涉及的唯一类不继承std::enable_shared_from_this<>。您正在创建一个ILogManager从指向 的共享指针ILogManager。这就是编译器为 \xe2\x80\x93 生成的代码shared_ptr,为不继承自enable_shared_from_this. 构造函数不知道您期望它初始化一个enable_shared_from_this子对象。

\n

LogManagerFactory::Create()如果将from的返回类型更改为 ,则该代码将ILogManager*起作用LogManager*std::shared_ptr<ILogManager>只要构造参数带入LogManager图片中,您就可以保留该零件。

\n

注意:为了更安全,LogManagerFactory::Create()应该返回 aunique_ptr或 ashared_ptr而不是原始指针,以清楚地传达调用者获得所有权。

\n