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

如何传递shared_ptr给需原始指针的构造函数并更新引用计数?

问题:传递shared_ptr给要求原始指针的构造函数时保持引用计数

我在创建QtNodes::GraphicsView的std::shared_ptr时执行了以下代码:

mGraphicsView = std::make_shared<QtNodes::GraphicsView>(mGraphicsScene, parent);

该构造函数要求传入QtNodes::BasicGraphicsScene*类型参数,但我持有的是该对象的std::shared_ptr<QtNodes::DataFlowGraphicsScene>(DataFlowGraphicsScene是BasicGraphicsScene的子类)。直接传递shared_ptr会触发如下编译错误:

cannot convert argument 1 from 'std::shared_ptr<QtNodes::DataFlowGraphicsScene>' to 'QtNodes::BasicGraphicsScene *'

使用.get()获取原始指针可以编译通过,但这种方式不会增加shared_ptr的引用计数,存在对象在仍被GraphicsView使用时就被销毁的风险。请问如何传递指针的同时正确更新引用计数?


解决方案

方式一:修改GraphicsView的构造函数参数(最优解)

如果有权限修改QtNodes::GraphicsView的代码,直接把构造函数的第一个参数从QtNodes::BasicGraphicsScene*改成std::shared_ptr<QtNodes::BasicGraphicsScene>。这样直接传入mGraphicsScene即可——因为std::shared_ptr支持向上转型,子类的shared_ptr可以自动转换为父类的shared_ptr,同时引用计数会正常增加,彻底避免悬空指针问题。

方式二:在GraphicsView内部存储std::weak_ptr(无法修改构造函数时的替代方案)

如果没法修改GraphicsView的构造函数,可在GraphicsView类内部添加一个std::weak_ptr<QtNodes::BasicGraphicsScene>成员。构造时先将子类的shared_ptr向上转型为父类的shared_ptr,再把这个shared_ptr转成weak_ptr存储起来,同时用.get()传递原始指针给构造函数:

// 先将子类shared_ptr转型为父类shared_ptr
auto parentScenePtr = std::static_pointer_cast<QtNodes::BasicGraphicsScene>(mGraphicsScene);
// 创建GraphicsView,传入原始指针
mGraphicsView = std::make_shared<QtNodes::GraphicsView>(parentScenePtr.get(), parent);
// 在GraphicsView的构造函数中,将传入的shared_ptr转存为weak_ptr
// mSceneWeak = parentScenePtr;

后续GraphicsView需要使用场景对象时,调用mSceneWeak.lock()获取std::shared_ptr——只有当对象还存在时,lock()才会返回有效的shared_ptr,同时增加引用计数,确保对象在使用期间不会被销毁。

不推荐的临时方案

如果能绝对保证mGraphicsScene的生命周期比mGraphicsView更长,那么直接使用.get()也能运行。但这种依赖生命周期假设的写法非常脆弱,一旦代码后续变更打破这个假设,就会出现悬空指针导致崩溃,不建议在复杂项目中使用。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 15:55:17