You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用shared_from_this时触发std::bad_weak_ptr错误的求助

问题:调用shared_from_this触发std::bad_weak_ptr错误

我已查阅过所有关于使用shared_from_this传递已有shared_ptr实例时触发std::bad_weak_error的相关问题,但均与我的情况不符:

  • 在调用shared_from_this()前,已存在该类的shared_ptr实例
  • 类已公有继承std::enable_shared_from_this<>

复现代码

#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

问题根源

问题出在shared_ptr的构造逻辑上:你用std::shared_ptr<ILogManager>托管LogManager实例,但enable_shared_from_this<LogManager>内部的weak_ptr需要由**指向LogManager本身的shared_ptr**来初始化。当你用基类ILogManager的指针构造shared_ptr时,这个shared_ptr不会关联到LogManager继承的enable_shared_from_this中的weak_ptr,导致后续调用shared_from_this()时,内部weak_ptr未被初始化,抛出bad_weak_ptr异常。

修复方案

方案一:工厂直接返回std::shared_ptr<ILogManager>

修改LogManagerFactory的Create方法,直接创建指向LogManager的shared_ptr,这样能正确触发enable_shared_from_this的初始化:

class LogManagerFactory {
public:
    static std::shared_ptr<ILogManager> Create()
    {
        return std::make_shared<LogManager>();
    }
};

方案二:转换派生类指针后构造shared_ptr

如果必须保留工厂返回原始指针的形式,在main中先将ILogManager*转换为LogManager*,再构造shared_ptr:

int main()
{
    auto rawLogManager = LogManagerFactory::Create();
    auto logManager = std::shared_ptr<LogManager>(static_cast<LogManager*>(rawLogManager));
    auto logger = logManager->GetLogger();
}

原理补充

std::enable_shared_from_this的工作机制是:当第一个指向该类实例的shared_ptr<T>被创建时,它会自动初始化enable_shared_from_this内部的weak_ptr<T>。如果创建的是指向基类的shared_ptr<Base>,而enable_shared_from_this属于派生类Derived,那么基类的shared_ptr不会触发派生类中enable_shared_from_this的初始化逻辑,最终导致shared_from_this()调用失败。

内容的提问来源于stack exchange,提问作者LKB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 21:50:38