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

C++对象从函数返回后类型信息变为基类的原因是什么?

前提说明

你给出的示例代码存在一处笔误:第一处typeid(derived)的操作数是std::shared_ptr<Derived>类型的智能指针对象,正常输出应为智能指针的类型名而非Derived,因此以下分析默认你实际代码中该处为typeid(*derived).name(),即对智能指针指向的派生类对象做类型识别。
同时你给出的示例代码本身存在严重未定义行为:makeDerived中的局部std::shared_ptr<Derived>会在函数返回时析构,若没有其他智能指针持有指向的Derived对象,对象会被释放,返回的Base&是悬空引用,main中对该引用的所有操作(包括typeid调用)结果均不可预期,这很可能是你无法稳定复现问题的核心原因。


会出现输出Derived, Base的几种常见情况

  • Base类不具备多态性
    C++标准明确规定:只有当typeid的操作数是多态类类型(类中至少定义了一个虚函数)的glvalue时,才会触发运行时动态类型识别,否则直接返回表达式的静态类型对应的type_info。
    若你的Base类没有定义任何虚函数,那么main中typeid(derived)的操作数静态类型是Base&,会直接返回Base的类型信息;而makeDerived中typeid(*derived)的静态类型是Derived,返回Derived的类型信息,完全符合你遇到的输出结果。
  • 返回的引用实际绑定到了Base类型的对象
    若secondLayer返回的智能指针实际指向的是Base类的实例,你通过不安全的指针转换(比如static_pointer_cast、C风格强转)将其赋值给了std::shared_ptr<Derived>,那么引用绑定的对象本身就是Base类型,typeid自然返回Base的类型信息。
  • RTTI被禁用或被破坏
    若你开启了关闭运行时类型识别的编译选项(比如GCC/Clang的-fno-rtti),typeid的动态识别功能会失效,只会返回表达式的静态类型;另外悬空引用导致的内存越界、对象析构后内存被复用为Base对象等内存错误,也可能破坏RTTI信息,导致输出异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 01:06:05