C++基础#21:C++中的RTTI机制之typeid

c++关键字之typeid typeid是 C++ 中用于获取运行时类型信息的操作符,主要通过返回对象来实现。可以用于判断对象的类型,尤其在多态场景中,有助于实现动态类型检查和运行时类型比较。使用时要注意多态性要求和对空指针的处理,避免意外的异常抛出。通过使用typeid,可以在运行时检查对象的类型,对于处理多态对象、调试代码以及实现更复杂的动态类型逻辑非常有用,但要注意不同编译器对type_info的实现细节可能有所不同,特别是name()方法返回的字符串表示。 阅读详情

简介:

RTTI,Runtime Type Information,即运行时类型信息,它提供了运行时确定对象类型的方法。

通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型。c++通过下面两个操作符提供RTTI。
(1)typeid:返回指针或引用所指对象的实际类型。
(2)dynamic_cast:将基类类型的指针或引用安全的转换为派生类型的指针或引用。
对于带虚函数的类,在运行时执行RTTI操作符,返回动态类型信息;对于其他类型,在编译时执行RTTI,返回静态类型信息。

上以节中,已经介绍了dynamic_cast的用法,本节主要来看typeid的用法。

 数据类型转换系列文章:

C++中的动态强制dynamic_cast

C++中的RTTI机制之typeid

C++中的静态强制static_cast

C++中的reinterpret_cast数据类型转换

C++中的const_cast数据类型转换

typeid的使用举例:

代码例子1:typeid用在普通类型

#include <iostream>
#include <typeinfo>
using namespace std;



int main()
{
     short s1 = 5;
     unsigned ui1 = 20;
     int i1 = 50, i2 = 100;
     char ch1 = 'a';
     wchar_t wch1 = L'b';
     float f1 = 3.14159265f;

     cout<<"typeid name:"<<endl;

     cout<<typeid(s1).name()<<endl;    // s
     cout<<typeid(ui1).name()<<endl;   // j
     cout<<typeid(i1).name()<<endl;    // i
     cout<<typeid(ch1).name()<<endl;   // c
     cout<<typeid(wch1).name()<<endl;  // w
     cout<<typeid(f1).name()<<endl;    // f
     
     cout<<"typeid compare result:"<<endl;

     if (typeid(i1) == typeid(i1)) {
          cout<<"typeid(i1) == typeid(i2)"<<endl; //执行到这个语句(类型相等)
     }else {
          cout<<"typeid(i1) != typeid(i1)"<<endl; 
     }

     if (typeid(s1) == typeid(i1)) {
          cout<<"typeid(s1) == typeid(i1)"<<endl;
     }else {
          cout<<"typeid(s1) != typeid(i1)"<<endl; //执行到这个语句(类型不相等)
     }

     return 0;
}
/*
编译环境:mac os下用g++编译:
MacBook-Pro cpp_stu % g++ typeid_test1.cpp
*/

代码例子2:typeid用在类类型

1) 

#include <iostream>
#include <typeinfo>
using namespace std;

class Base {
public:
    int a;
    virtual void fun1() {cout<<"Base::fun1"<<endl;}
    virtual void fun2() {cout<<"Base::fun2"<<endl;}
    virtual void fun3() {cout<<"Base::fun3"<<endl;}
};

class A {
public:
    int a;
    
};

class Derive : public Base{
public:
    int b;
    void fun2() {cout<<"Derive::fun2"<<endl;}
};

int main()
{
    
     Base b;
     Derive d;
     A a;

     cout<<typeid(b).name()<<endl; // 4Base
     cout<<typeid(d).name()<<endl; // 6Derive
     cout<<typeid(a).name()<<endl; // 1A
     
     cout<<"compare result:"<<endl;

     if (typeid(b) == typeid(d)) {
          cout<<"typeid(b) == typeid(d)"<<endl;
     }else {
          cout<<"typeid(b) != typeid(d)"<<endl; //执行到这个语句
     }

     return 0;
}
/*
编译环境:mac os下用g++编译:
MacBook-Pro cpp_stu % g++ typeid_test2.cpp
*/

运行结果:

4Base

6Derive

1A

compare result:

typeid(b) != typeid(d)

分析:

2)

再看下面的代码:

     Derive d;
     Derive *pD = new Derive();

     cout<<typeid(pD).name()<<endl; // P6Derive

     if (typeid(d) == typeid(pD)) {
          cout<<"typeid(d) == typeid(pD)"<<endl;
     }else {
          cout<<"typeid(pD) != typeid(pD)"<<endl; //执行到这个语句
     }

显然,pD是指针类型,typeid(pD).name()的结果是P6Derive,而不是6Derive。

3)

再看一个例子,把上面的

Derive *pD = new Derive();

改为:

Base *pB = new Derive();, 如下:

     Derive d;
     Base *pB = new Derive();

     cout<<typeid(pB).name()<<endl; // P4Base
     cout<<typeid(*pB).name()<<endl; // 6Derive
     
     cout<<"compare result:"<<endl;

     if (typeid(d) == typeid(*pB)) {
          cout<<"typeid(d) == typeid(*pB)"<<endl; //执行到这个语句
     }else {
          cout<<"typeid(pD) != typeid(*pB)"<<endl; 
     }

运行结果:

P4Base

6Derive

compare result:

typeid(d) == typeid(*pB)

分析:

d和 *pB的类型一样,都是Derive类型。

4)

上面的例子中,Base是虚基类(有虚函数),现在如果我们把Base改为非虚基类,看看typeid的结果如何。代码如下:

#include <iostream>
#include <typeinfo>
using namespace std;

class Base {
public:
    int a;
    void fun1() {cout<<"Base::fun1"<<endl;}
    void fun2() {cout<<"Base::fun2"<<endl;}
    void fun3() {cout<<"Base::fun3"<<endl;}
};

class Derive : public Base{
public:
    int b;
    void fun2() {cout<<"Derive::fun2"<<endl;}
};

int main()
{

     Derive d;
     Base *pB = new Derive();

     cout<<typeid(pB).name()<<endl;  // P4Base
     cout<<typeid(*pB).name()<<endl; // 4Base
     
     cout<<"compare result:"<<endl;

     if (typeid(d) == typeid(*pB)) {
          cout<<"typeid(d) == typeid(*pB)"<<endl;
     }else {
          cout<<"typeid(pD) != typeid(*pB)"<<endl; //执行到这个语句
     }

     return 0;
}
/*
编译环境:mac os下用g++编译:
MacBook-Pro cpp_stu % g++ typeid_test3.cpp
*/

运行结果:

P4Base

4Base

compare result:

typeid(pD) != typeid(*pB)

分析:

Base *pB = new Derive();  

创建的是Derive实例,但是typeid(*p B)的结果是4Base类型,而我们期望的是真正创建的对象的类型,即Derive。

这就是没有将父类定义成虚基类(包含virtual函数)的弊端。


C++ `typeid` 运算符 阅读详情

相关推荐

C++ 知识补充

向量(vector)是一个封装了动态大小数组的顺序容器(SequenceContainer)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。C++中map提供的是一种键值对容器,里面的数据都是成对出现的,如下图:每一对中的第一个值称之为关键字(key),每个关键字只能在map中出现一次;第二个称之为该关键字的对应值。

weixin_47059239的博客 2128

ROS C++消息Traits机制:编译期元数据与序列化原理

ROS消息类型不是简单的结构体,而是一套由编译期元数据(Traits)定义的通信契约。其核心在于MD5Sum、IsMessage、IsFixedSize等模板特化,它们在编译阶段静态确定消息的二进制结构、序列化行为与跨节点兼容性。这种零开销抽象避免了RTTI运行时开销,保障机器人系统的实时性与确定性;同时支撑rostopic、rosbag、rviz等工具链的类型识别与数据解析。理解Traits,就是理解ROS C++客户端如何将.msg定义安全、高效地映射为可执行的序列化逻辑——尤其当遇到rostopic

weixin_33981932的博客 293

C++(03):获取类型信息的typeid运算符

typeid 运算符用来获取一个类型的类型信息,他的操作对象可以是表达式,也可以是数据类型: typeid( dataType ) typeid( expression ) typeid 会把获取到的类型信息保存到一个 type_info 类型的对象里面,并返回该对象的常量引用;可以通过成员函数name()来提取类型信息字符串,但C++没有规定name()返回的字符串格式,所以不同的编译器返回的格式是不一样的。 此外typeid还可以用于的判断。 #include <iostream>

风静如云的博客 928

C++ typeid关键字详解

C++ typeid关键字详解

路过的熊的博客 6615

unity转微信小游戏:UI大小设置

unity转微信小游戏:UI大小设置

会潜水的小火龙的博客 3266

拯救者R7000P(2021)装双系统Ubuntu20.04 解决联发科MT7921无线网卡在Ubuntu中不能联网

拯救者R7000P(2021)装双系统Ubuntu20.04/Ubuntu18.04 电脑配置:联想拯救者R7000P CPU:AMD R7-5800H GPU:RTX3060-6G 内存:16GB 固态:500G(原装)+500(加装) 1.做系统盘(本文以Ubuntu20.04为例) 1.下载Ubuntu20.04镜像 直接去Ubuntu官网或者一些国内的镜像去下载都可以,这里给出一个网址https://ubuntu.com/download/desktop,根据需要下载自己学要的Ubuntu版本,后缀

qq_41108639的博客 1万+

C++ 编程基础(9)RTTI(Runtime Type Information)机制

C++中的RTTI机制提供了一种在运行时查询和操作类型信息的强大工具。然而,它并不是万能的,也有其限制和潜在的问题。开发者在使用RTTI时需要权衡其利弊,并根据具体的应用场景和需求来做出决策。在可能的情况下,应优先考虑使用C++的其他特性(如模板、多态等)来实现类型安全和灵活性的需求。

个人技术博客 3577

FPGA实战:用Verilog实现Costas环载波同步(附Vivado2019.2仿真步骤)

本文详细介绍了如何在FPGA上使用Verilog实现Costas环载波同步,包括核心原理、Vivado2019.2工程配置、代码实现及仿真验证。通过正交下变频、相位误差检测和环路滤波等关键模块的设计,帮助开发者掌握数字通信系统中的载波同步技术,并提供了实用的调试和优化技巧。

k0l1m2n3o的博客 134

【C/C++基础回顾与总结】

个人关于C/C++基础学习的回顾与总结

weixin_44914838的博客 480

【深度解析】信息素养提升实践活动(附:历年获奖作品分析)

全国师生信息素养提升实践活动是由教育部教育技术与资源发展中心(中央电化教育馆)主办,面向全国师生的一项信息化交流展示活动。

m0_74417957的博客 2627

Redhawk: 为什么STA CHECK中switch cell覆盖率为0(STA file中switch control pin没有timing window)?

如题,做dynamic analysis时,不需要switch cell的timing window信息,但是做low power analysis需要做上电时switch cell的timing window就是必须的了,本文对switch cell control pin没有timing window (STA CHECK覆盖率为零)的这种现象做分析。

m0_61544122的博客 1193

虚函数表里有什么?(一)——从一个普通类开始

在没有虚拟继承的情况下(正如本文中的例子),vtable的起始8个字节中会保存一个偏移量,通常被称为top_offset。它记录了基类子对象首地址到最派生类对象(也称为完整对象,就是继承体系中辈分最小的那个对象)首地址的偏移量。它的本质作用就是通过基类子对象找到完整对象,具体地,通常在以下场景中使用。调用虚函数时调整this指针。通过进行向下类型转换。在异常处理中需要定位完整对象。需要注意的是,这里的基类子对象必须是多态对象(),即声明或继承了至少一个虚拟函数的对象。

weixin_30769455的博客 80

深度解析:C# Modbus TCP协议解析与异常处理(工控上位机必备)

协议解析要精准:掌握MBAP头和PDU的结构,尤其是常用功能码的请求/响应格式,避免因字节处理错误导致通信失败;异常处理要全面:覆盖通信层、协议层、数据层的所有异常类型,针对工业场景制定重试、重连、滤波等策略;资源管理要规范:使用释放资源,采用连接池复用连接,避免端口泄露;工业场景要适配:结合工控现场的特点(网络波动、电磁干扰、设备忙),优化通信效率和数据处理逻辑。通过以上解析和策略,可确保C#上位机与工业设备的Modbus TCP通信具备高稳定性、高可靠性、高容错性,满足工控领域的严苛要求。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 995

C++学习

C++基础学习、函数模板、动态内存、新特性、面向对象编程、类的设计以及STL标准模板库的学习

2601_94965056的博客 223

图像处理之边缘检测[微分算子、Canny算子和LOG算子]

LOG算子是在经典算子的基础上发展起来的边缘检测算子,根据信噪比求得检测边缘的最优滤波器。边缘总是以强度突变的形式出现,可以定义为图像局部特性的不连续性,如灰度的突变和纹理结构的突变等。图像的边缘包含了物体形状的重要信息,它不仅在分析图像时大幅度地减少了要处理的信息量,而且还保护了目标的边界结构。对于复杂的图像,采用Roberts算子不能较好地得到图像的边缘,而需要采用更加复杂的3X3的算子比如Prewitt算子。对于离散的图像f(x,y),边缘检测算子是用图像的垂直和水平差分来逼近梯度算子,即。

qq_44111805的博客 9833

Python爬虫模拟登录京东并抓取商品数据

京东是一个拥有海量商品数据的电子商务平台。作为爬虫开发者,能够抓取这些数据将为我们提供很多机会进行数据分析、价格预测、市场调研等工作。然而,京东的反爬虫机制非常强大,包括但不限于验证码、动态加载页面、IP封禁等。因此,想要通过Python爬虫抓取京东的数据并不容易。在本文中,我们将从分析京东的登录机制开始,逐步介绍如何使用Python中的各种工具,如。

2201_76125261的博客 1826

PowerPC VLE指令集与ROM镜像构建:嵌入式开发代码密度优化实战

在嵌入式系统开发中,代码密度是影响成本与性能的关键指标,它直接关系到芯片选型、启动速度与缓存效率。变长编码指令集通过混合16位与32位指令,在保持性能的同时显著压缩代码体积,其原理在于对常用简单操作采用短指令编码。这项技术为资源受限的微控制器带来了实质的工程价值,广泛应用于汽车电子控制器、工业网关等对Flash空间敏感的场景。链接器脚本作为内存布局的总设计师,定义了程序各段在ROM与RAM中的规划,是实现可靠ROM镜像的核心。本文聚焦Power Architecture处理器的VLE指令集应用与ROM镜像构

490

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++中的typeid

typeid是 C++ 中的运算符,用于获取表达式或类型的运行时类型信息。它返回一个std::type_info对象,该对象包含有关类型的信息,例如类型的名称。

m0_61629312的博客 2031

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++ typeid详解

C++为我们提供了一种可以判断变量类型的关键字,即typeid,它的参数和sizeof一样,可以是一个变量,或者一种类型。typeid的返回值是type_info类,而且返回的是一个左值。type_info类禁用了拷贝构造函数,因此我们必须要用引用或指针来存储结果,如: const type_info& type1=typeid(int); const type_info* type2=&typeid(int); name() 作用:返回描述变量类型的字符串(注意:是类型全名)。 基本用法

[PE]经典八炮的博客 9233

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

c++关键字typeid

typeid是c++的一个关键字,typeid操作符的返回结果是标准库类型type_info对象的引用。 但是,C++标准并没有明确定义type_info,其具体实现依赖于各个编译器。标准只规定了typeid操作符必需实现如下四种操作: 操作 说明 t1 == t2 如果两个对象t1和t2类型相同,则返回true;否则返回false t1 != t2 如果两个对象t1和t2类型不同,则返回true;否则返回false t.name() 返回类型的C-style字符串。由编..

吴尼玛cs 634

C++之typeid的介绍

C++之typeid的介绍

techenliu的博客 637

C++11新特性之typeid关键字使用

typeid运算符用来获取一个表达式的类型信息。类型信息对于编程语言非常重要,它描述了数据的各种属性:对于基本类型(int、float 等C++内置类型)的数据,类型信息所包含的内容比较简单,主要是指数据的类型。对于类类型的数据(也就是对象),类型信息是指对象所属的类、所包含的成员、所在的继承关系等。typeid运算符返回一个std::type_info对象,表示表达式的实际类型。

悟空爱编程 1383

C++ 类型(typeid、RTTI、decltype等)

1,typeid操作符 用法和sizeof很像,既可以用于变量,也可以用于类型,作用是指出他们的类型。 #include<iostream> #include <c++/memory> using namespace std; class A { }; int main() { cout<<typeid(12).name()<<" "; cout<<typeid(int).name()<<" "; ...

nameofcsdn的博客 2468

c++的关键字typeid

文章目录一、什么typeid?二、怎么用typeid 一、什么typeid? 二、怎么用typeid 注意:typeid的定义和声明是在typeinfo中,所以预编译头文件的时候需要包含#include。 #include<iostream> #include<typeinfo> //必须要包含该头文件 using namespace std; int main() { int a = 0; double b = 2.0; cout <&lt

weixin_44355245的博客 399

C++中的typeid关键字

用以返回一个变量或数据类型的“类型”。用法如下:coutint a;cout输出如下:intint关于typeid的错误(warning C4541: 'typeid' used on polymorphic type 'class A' with /GR-; unpredictable behavior may result):解决方法:在vc6中. Project - settings... - C/C++ ,在Category那里选 C++ Language,再在下边勾上 Enable Run-Tim

viclee 1万+
上一篇: Android基础#16:Android利用adb bugreport获取设备运行信息
下一篇: source insight 快捷键一览
liranke
博客等级 码龄20年 4939粉丝 594原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值