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

使用enable_shared_from_this触发bad_weak_ptr异常,如何解决?

问题:shared_from_this() 触发 bad_weak_ptr 异常

代码背景

基类eventreceiver定义:

class eventreceiver {
public:
  eventreceiver() = default;
  virtual ~eventreceiver() = default;

  virtual void on_quit();
};

继承自eventreceiver和std::enable_shared_from_this<engine>的engine类:

class engine : public eventreceiver, std::enable_shared_from_this<engine> {
public:
  virtual ~engine() = default;

  [[nodiscard]] static std::shared_ptr<engine> create();

  void init(std::string_view title, int32_t width, int32_t height, bool fullscreen = false);

  void add_loopable(std::shared_ptr<loopable> loopable);

  void run();

protected:
  virtual void on_quit() override;

private:
  engine() = default;

  bool _running;

  std::list<std::shared_ptr<loopable>> _loopables;
  std::shared_ptr<window> _window;
  std::shared_ptr<renderer> _renderer;
  std::shared_ptr<eventmanager> _eventmanager;
};

engine::init方法实现:

void engine::init(std::string_view title, int32_t width, int32_t height, bool fullscreen) {
  _running = true;
  _window = std::make_shared<window>(title, width, height, fullscreen);
  _renderer = _window->create_renderer();
  _eventmanager = std::make_shared<eventmanager>();

  _eventmanager->add_receiver(std::dynamic_pointer_cast<eventreceiver>(shared_from_this())); // 触发bad_weak_ptr异常

  add_loopable(std::make_shared<framerate>());
}

问题描述

调用engine::init时,shared_from_this()触发bad_weak_ptr异常,如何正确将engine的shared_ptr传递给_eventmanager?


解决方案

错误原因

  1. std::enable_shared_from_this继承权限错误
    在多继承列表中,仅第一个基类eventreceiver显式声明为public继承,第二个基类std::enable_shared_from_this<engine>默认采用private继承。而std::enable_shared_from_this要求必须公有继承,否则std::shared_ptr无法访问其内部的weak_ptr成员完成初始化,调用shared_from_this()时就会抛出异常。

  2. (潜在风险)对象未被std::shared_ptr持有
    若engine::create()方法未正确返回持有当前对象的shared_ptr,或在shared_ptr创建前调用init,也会导致shared_from_this()无法获取有效指针。

修复步骤

  1. 修正enable_shared_from_this的继承权限
    将std::enable_shared_from_this<engine>改为公有继承:

    class engine : public eventreceiver, public std::enable_shared_from_this<engine> {
        // 原有代码保持不变
    };
    
  2. 确保create()方法正确返回shared_ptr
    实现create()时,必须返回持有engine对象的shared_ptr,推荐使用std::make_shared:

    std::shared_ptr<engine> engine::create() {
        return std::make_shared<engine>();
    }
    
  3. 正确调用init的时机
    必须在shared_ptr创建完成后调用init:

    auto engine_inst = engine::create();
    engine_inst->init("My App", 800, 600);
    
  4. 优化指针转换(可选)
    由于engine是公有继承eventreceiver,可以用static_pointer_cast替代dynamic_pointer_cast,提升效率:

    _eventmanager->add_receiver(std::static_pointer_cast<eventreceiver>(shared_from_this()));
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 03:34:55