如何使用`typeid`判断指针或引用所指对象的实际类型?

核心前提:typeid判断实际类型的条件

typeid能否识别指针 / 引用指向的实际类型,唯一的关键是:被判断的类是否是多态类(包含至少一个虚函数,通常是虚析构函数)

  • 非多态类:typeid只能识别编译期的声明类型(静态类型)。
  • 多态类:typeid会解析运行时的实际对象类型(动态类型)。

一、判断指针指向对象的实际类型

关键注意点

使用typeid判断指针时,必须解引用指针typeid(*ptr)),如果直接写typeid(ptr),得到的只是 “指针类型” 本身(如Base*),而非指向对象的类型。

代码示例(对比多态 / 非多态类)

cpp

运行

#include <iostream> #include <typeinfo> // 1. 非多态基类(无虚函数) class NonPolymorphicBase { public: void func() {} // 普通成员函数 }; class NonPolymorphicDerived : public NonPolymorphicBase {}; // 2. 多态基类(有虚函数) class PolymorphicBase { public: virtual ~PolymorphicBase() = default; // 虚析构,使类多态 virtual void func() {} }; class PolymorphicDerived : public PolymorphicBase {}; int main() { // ---------------------- 非多态类测试 ---------------------- NonPolymorphicBase* np_base_ptr = new NonPolymorphicDerived(); // 错误:直接判断指针类型(得到的是指针本身的类型) std::cout << "非多态-直接判断指针: " << typeid(np_base_ptr).name() << std::endl; // 结果:NonPolymorphicBase*(编译器可能简写为P19NonPolymorphicBase) // 非多态类:即使解引用,仍返回编译期声明类型(Base) std::cout << "非多态-解引用指针: " << typeid(*np_base_ptr).name() << std::endl; // 结果:NonPolymorphicBase(而非Derived) // ---------------------- 多态类测试 ---------------------- PolymorphicBase* p_base_ptr = new PolymorphicDerived(); // 错误:直接判断指针类型(得到的是指针本身的类型) std::cout << "多态-直接判断指针: " << typeid(p_base_ptr).name() << std::endl; // 结果:PolymorphicBase*(编译器可能简写为P16PolymorphicBase) // 多态类:解引用后,返回运行时实际类型(Derived) std::cout << "多态-解引用指针: " << typeid(*p_base_ptr).name() << std::endl; // 结果:PolymorphicDerived // ---------------------- 类型比较 ---------------------- // 判断指针指向的对象是否是指定的实际类型 if (typeid(*p_base_ptr) == typeid(PolymorphicDerived)) { std::cout << "指针指向的是PolymorphicDerived类型对象" << std::endl; } // 释放内存 delete np_base_ptr; delete p_base_ptr; return 0; }

二、判断引用所指对象的实际类型

引用的特性是 “别名”,不存在空引用,因此使用typeid判断引用时:

  • 无需解引用(引用本身就是对象的别名);
  • 同样遵循 “多态类识别实际类型,非多态类识别声明类型” 的规则。
代码示例

cpp

运行

#include <iostream> #include <typeinfo> // 多态基类 class Base { public: virtual ~Base() = default; }; class Derived1 : public Base {}; class Derived2 : public Base {}; void check_ref_type(Base& ref) { // 直接判断引用,多态类会返回实际类型 if (typeid(ref) == typeid(Derived1)) { std::cout << "引用指向Derived1对象" << std::endl; } else if (typeid(ref) == typeid(Derived2)) { std::cout << "引用指向Derived2对象" << std::endl; } else { std::cout << "引用指向Base对象" << std::endl; } } int main() { Derived1 d1; Derived2 d2; Base b; Base& ref1 = d1; Base& ref2 = d2; Base& ref3 = b; check_ref_type(ref1); // 输出:引用指向Derived1对象 check_ref_type(ref2); // 输出:引用指向Derived2对象 check_ref_type(ref3); // 输出:引用指向Base对象 return 0; }

三、常见坑点与注意事项

  1. 不要直接判断指针类型typeid(ptr)得到的是 “指针类型”(如Base*),而非指向对象的类型,必须写typeid(*ptr)
  2. 空指针处理:如果指针是nullptr,对非多态类使用typeid(*ptr)会直接崩溃;对多态类,typeid(*ptr)仍会返回指针的声明类型(不会崩溃)。

    cpp

    运行

    PolymorphicBase* null_ptr = nullptr; std::cout << typeid(*null_ptr).name() << std::endl; // 输出PolymorphicBase(不会崩溃) NonPolymorphicBase* null_np_ptr = nullptr; std::cout << typeid(*null_np_ptr).name() << std::endl; // 未定义行为,大概率崩溃
  3. 类型名的可读性typeid(...).name()的返回值是编译器相关的(比如 GCC 会简写类型名,MSVC 会返回完整名),不要直接依赖字符串内容判断类型,优先用typeid(A) == typeid(B)的方式。
  4. 运行时开销:对多态类使用typeid会查询虚函数表(vtable),有轻微运行时开销,频繁使用会影响性能。

总结

  1. 核心条件:只有对多态类(含虚函数)的指针 / 引用,typeid才能识别指向对象的实际类型;非多态类仅能识别编译期声明类型。
  2. 指针判断:必须解引用(typeid(*ptr)),否则得到的是指针类型本身。
  3. 引用判断:直接使用typeid(ref)即可,多态类会返回实际对象类型。
  4. 安全建议:判断类型时优先用typeid(A) == typeid(B),而非解析name()字符串;空指针场景需先判空再使用typeid(*ptr)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1160607.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ RAII封装结构体成员变量自动加锁性能开销分析

在C中通过RAII&#xff08;Resource Acquisition Is Initialization&#xff09;机制封装结构体成员变量的自动加锁/解锁操作&#xff0c;其性能开销需从锁机制成本、编译器优化空间、运行时场景适配三个维度进行系统性分析&#xff1a; 一、RAII加锁封装的核心机制 以典型实现…

凤希AI提出FXPA2P:下一代点对点AI服务架构-2026年1月14日

思考与发现在今日对产品技术细节进行打磨与升级的同时&#xff0c;一个更为宏观和前瞻性的构想逐渐清晰。基于对当前AI应用依赖中心化云服务所暴露的成本、效率与隐私问题的深刻洞察&#xff0c;我们正式提出 FXPA2P 这一商业概念与技术实施模式。FXPA2P&#xff0c;即 FengXi …

智能指针的生命周期控制

在C中&#xff0c;函数内创建的智能指针通过参数返回时&#xff0c;其生命周期管理遵循资源所有权转移和引用计数的智能指针语义&#xff0c;具体行为取决于智能指针类型&#xff08;如std::unique_ptr、std::shared_ptr&#xff09;和传递方式&#xff08;返回值/输出参数&…

AI原生应用开发:相似度匹配的模型压缩技巧

AI原生应用开发:相似度匹配的模型压缩技巧 关键词:相似度匹配、模型压缩、AI原生应用、知识蒸馏、模型量化、参数剪枝、轻量级模型 摘要:在AI原生应用(如智能推荐、跨模态搜索、对话系统语义理解)中,相似度匹配模型是核心组件。但这类模型常因参数量大、计算复杂度高,难…

6款AI论文降重神器实操教程:AI率从72%降至13%

一、AI论文降重工具快速对比&#xff1a;哪款最适合你&#xff1f; 作为学生或科研人员&#xff0c;你是否曾遇到以下痛点&#xff1a; 用ChatGPT写的论文AI检测率高达70%&#xff0c;被导师打回重写&#xff1f;降重时逐句改写&#xff0c;耗时又容易破坏逻辑&#xff1f;找…

Python + uiautomator2 手机自动化控制教程

安装 uiautomator2 库通过 pip 安装 uiautomator2 库&#xff0c;确保 Python 环境已配置。pip install uiautomator2初始化设备连接使用设备的 IP 地址或序列号连接手机&#xff0c;确保手机已开启 USB 调试模式。import uiautomator2 as u2 d u2.connect("192.168.1.10…

Python 学生管理系统实战:从基础功能到数据持久化(附完整源码)

学生管理系统基础功能实现学生管理系统的核心功能包括添加、删除、修改和查询学生信息。使用Python内置数据结构如字典和列表可以快速实现这些基础功能。students []def add_student():name input("输入学生姓名: ")age int(input("输入学生年龄: "))st…

【Python库和代码案例:第一课】Python 标准库与第三方库实战指南:从日期处理到 Excel 操作

Python 标准库实战datetime 模块处理日期from datetime import datetime, timedelta# 获取当前时间 now datetime.now() print(f"当前时间: {now}")# 时间加减操作 next_week now timedelta(days7) print(f"一周后时间: {next_week}")# 时间格式化 form…

数独优化求解C库tdoku-lib的使用

tdoku-lib是基于优化求解器tdoku改造的动态库和静态库&#xff0c;它的存储库地址 https://github.com/hackerzhuli/tdoku-lib 1.拉取源代码 rootDESKTOP-59T6U68:/mnt/c/d# git clone https://github.com/hackerzhuli/tdoku-lib.gitCloning into tdoku-lib... remote: Enumer…

AI原生应用云端推理的故障排查与恢复

AI原生应用云端推理的故障排查与恢复:让智能服务“不掉线”的秘密 关键词:AI原生应用、云端推理、故障排查、恢复机制、AIOps 摘要:当你用手机拍照识别植物品种时,当智能客服秒级回复你的问题时,当电商APP精准推荐商品时——这些“丝滑”体验的背后,是AI原生应用在云端高…

dlx求解数独duckdb插件的编写和使用

1.将网上下载的dlx求解c程序添加int sudoku(const char *s,char *r)函数处理81个字符长的数独题目字符串 #include <cstdio> #include <cstring> #include <ctime> int cnt0; const int XSIZE 3; const int SIZE XSIZE * XSIZE; const int MAX_C SIZE *…

我用 XinServer 做了个文件系统,比想象简单

我用 XinServer 做了个文件系统&#xff0c;比想象简单 最近有个朋友找我帮忙&#xff0c;说他们团队想做个内部文件管理系统&#xff0c;让不同部门的同事能上传、下载、共享文档&#xff0c;还要有权限控制。他问我&#xff1a;“这个后端大概要搞多久&#xff1f;我们前端倒…

大数据领域数据产品的安全保障策略

大数据领域数据产品的安全保障策略&#xff1a;从全生命周期到体系化防御 引言&#xff1a;当大数据产品遇到安全“灰犀牛” 清晨打开手机&#xff0c;你收到一条推送&#xff1a;“某电商平台2000万用户信息泄露&#xff0c;含手机号、地址、购物记录”&#xff1b;下午参加…

避坑指南:通义千问2.5-7B-Instruct本地部署常见问题解决

避坑指南&#xff1a;通义千问2.5-7B-Instruct本地部署常见问题解决 1. 引言 1.1 业务场景描述 随着大模型在企业级应用和开发者项目中的普及&#xff0c;越来越多团队选择将高性能、可商用的开源模型部署至本地环境&#xff0c;以实现数据隐私保护、低延迟响应和定制化功能…

【RuoYi-SpringBoot3-Pro】:使用 Dify + AI 快速生成多数据库建表语句

【RuoYi-SpringBoot3-Pro】&#xff1a;使用 Dify AI 快速生成多数据库建表语句告别手写 SQL&#xff0c;一句话生成标准化建表语句&#xff0c;支持 MySQL、PostgreSQL、openGauss、SQLite 多种数据库&#xff0c;再也不用为给字段起名字发愁了。GitHub:https://github.com/u…

AnimeGANv2版本回滚机制:模型更新失败应急部署教程

AnimeGANv2版本回滚机制&#xff1a;模型更新失败应急部署教程 1. 引言 1.1 业务场景描述 在AI图像风格迁移应用中&#xff0c;AnimeGANv2 因其轻量高效、画风唯美的特性&#xff0c;广泛应用于二次元头像生成、社交内容创作等场景。随着模型迭代加速&#xff0c;开发者常通…

这份无线联网智能门锁系统清单非常专业,清晰地勾勒出了一套适用于多业态、高流动性、强管理场景的现代化出入口解决方案。这不仅是设备清单,更是一套“去中心化部署、云端化管理”的智慧运营蓝图。

无线联网智能门锁系统——专为公寓、办公、宿舍、民宿与酒店打造的全场景智能门禁解决方案这套无线联网智能门锁系统&#xff0c;专为高流动性、多权限管理的场景设计&#xff0c;已广泛应用于公寓、企业宿舍、办公场所、民宿及酒店等环境&#xff0c;实现“一卡通行、远程管控…

【RuoYi-SpringBoot3-Pro】:多租户功能上手指南

【RuoYi-SpringBoot3-Pro】&#xff1a;多租户功能上手指南 做 SaaS 系统最头疼的是什么&#xff1f;肯定是数据隔离。 RuoYi-SpringBoot3-Pro[1] 直接集成了 MyBatis-Plus 的多租户插件&#xff08;TenantLineInnerInterceptor&#xff09;&#xff0c;不用再关注租户 ID&am…

提示工程架构师经验:如何用Prompt解决客服复杂问题?

提示工程架构师经验&#xff1a;如何用Prompt解决客服复杂问题&#xff1f; 一、引言&#xff1a;客服AI的「尴尬时刻」&#xff0c;你遇到过吗&#xff1f; 上周晚饭后&#xff0c;我帮妈妈处理网购纠纷——她买的养生壶收到时底座裂了&#xff0c;联系客服AI得到回复&#xf…

对象库未注册-VB6企业版控件加载不了MSCOMCTL.ocx

关于WIN7下VB6中MicrosoftWindowsCommonControls6.0(SP6)加载提示“对象库未注册”的一种解决办法​​我之前在另外一台电脑上加上了进度条控件&#xff0c;使用正常&#xff1b;换了一台电脑之后&#xff0c;去“部件”中加入Microsoft Windows Common Controls 6.0 (SP6)时&a…