C++中通过派生类实现返回基类shared_ptr的正确方法
问题根因
编译报错和运行时隐患来自三处核心问题:
- 类型不匹配:你在
getBase()中尝试将Derived*类型的对象地址&d,直接赋值给std::shared_ptr<Base>*类型的指针变量,二者是完全无关的类型,不存在隐式转换路径,编译器直接抛出类型转换错误。 - 智能指针使用逻辑错误:
std::shared_ptr的默认语义是持有动态分配对象的所有权,在引用计数归零时自动销毁管理的对象。你定义的d是全局静态存储期对象,生命周期贯穿程序整个运行周期,如果直接把d的地址交给默认构造的shared_ptr管理,会在智能指针析构时尝试释放静态存储区内存,触发段错误等未定义行为。 - 代码笔误:派生类头文件中
#inclide "base.hpp"属于拼写错误,需要修正为#include "base.hpp",否则会触发头文件找不到的编译错误。
正确实现方式
在保留现有类设计(Base禁用拷贝/移动、纯虚接口、全局派生类实例)的前提下,只需要修改getBase()的实现逻辑,给shared_ptr传入空删除器,声明该智能指针不持有对象所有权即可:
// getBase.cpp 修正后代码 #include "base.hpp" #include "derived.hpp" Derived d; std::shared_ptr<Base> getBase() { // 第二个参数是空删除器,引用计数归零时不会执行任何销毁操作,避免释放全局对象d return std::shared_ptr<Base>(&d, [](Base*) noexcept {}); }
补充说明
- 你现有的Base类设计是典型的不可拷贝纯虚接口类设计,派生类
Derived公有继承、重写Function1的写法完全符合接口规范,不需要调整。 - main.cpp中对
getBase()的调用逻辑不需要修改,拿到的shared_ptr<Base>可以正常触发多态调用Function1,行为符合预期。
内容的提问来源于stack exchange,提问作者Iti Tyagi
相关产品推荐
相关产品推荐

