运行时类型信息RTTI

Delphi RTTI(运行时类型信息) 如何根据名称找到控件如何根据名称找到对应的属性如何根据名称执行某个方法或事件 运行时类型信(以下简称RTTI)是在运行时保存和检索对象和数据类型的手段.通过RTTI我们可以了解正在使用的对象或组件的信息,并对它们进行一些处理.   RTTI需要引用单元TypInfo   至于RTTI的数据结构,大家可以参考TypeInfo单元的代码   看例子,先为大家介绍一下根据字符串找到属性,并 阅读详情

我们在写C++代码的时候经常碰到使用dynamic_cast进行类型转换的情况,也都知道经过dynamic_cast的转换更加安全,因为dynamic_cast进行了类型检查。 但是可能很多人不知道dynamic_cast是C++ 运行时类型信息(RTTI)机制链条上的一个节点。 RTTI提供了两个操作符和一个类:

  • dynamic_cast
  • typeid
  • type_info

整个RTTI, 作为一个整体,暴露给程序员的就是这三个元素。因此我们关注的焦点也就在它们身上了。


什么是RTTI

在C++中存在虚函数,也就存在了多态性,对于多态性的对象,其基类的指针可以指向任何派生类的对象,这时就有可能不知道基类指针到底指向的是哪个对象的情况,类型的确定要在运行时利用运行时类型标识做出。RTTI 就是语言内建的支持运行时识别对象的类型并提供类型信息的一套机制。


typeid 和 type_info

  • typeid 是一个操作符,提供对象的类型信息,基本用法是:
#include <typeinfo>
#include <iostream>

class Person {
   public: 
   virtual ~Person() {}
};

class Employee : public Person { };

int main()
{
    Person person;
    Employee employee;
    Person* ptr = &employee;
    Person& ref = employee;

    std::cout << typeid(int).name() << std::endl;
    std::cout << typeid(Employee).name() << std::endl; 
    std::cout << typeid(*ptr).name() << std::endl; 
    std::cout << typeid(ptr).name() << std::endl;
    std::cout << typeid(ref).name() << std::endl;

    return 0;
}

输出的结果是

int
class Employee
class Employee
class Person*
class Employee

从上面的代码可以看出,typeid操作符最常见的用法就是在运行时提供对象的真实类型信息(name), 接受的可以是 一个类型名或者一个表达式。
当输入的是一个指针时,typeid会识别为指针类型(class Person*而不是class Person), 但是typeid并不会把引用识别为引用,因此不会有class Person&这样的结果。也就是说输入引用和输入对象对于typeid是一回事,但是对于指针你得解引用!

  • 注意这里的类型或对象可以不是多态类型。
class Account{}; //没有虚函数非多态类型
Account acc;
Account& ref = acc;
std::cout << typeid(ref).name() << std::endl; //ok, 输出 class Account

虽然typeid支持这种非多态类型的查询,但是这些信息实际上在编译时就已经知道了,因此这样的用法更多得是为了完整性考虑,而没有多大的实际用处。

  • 抛出异常
Person* ptr = NULL;
void*   vptr = ptr;

try{
   std::cout << typeid(vptr).name() << std::endl;
}
catch(std::bad_typeid& e)
{ std::cout << "bad_typeid caught on vptr" << std::endl; }
catch(...){}

try{

   std::cout << typeid(ptr).name() << std::endl;
}
catch(std::bad_typeid& e)
{ std::cout << "bad_typeid caught on ptr" << std::endl; }
catch(...){}

try{ 
  std::cout << typeid(*ptr).name() << std::endl;
}
catch(std::bad_typeid& e)
{ std::cout << "bad_typeid caught on *ptr" << std::endl; }
catch(...){}

输出的结果是

void*
Person*
bad_typeid caught on *ptr

上面的例子可以看到对于空指针,typeid不会深入检查指针是否为空,而是仅仅返回指针的类型,但是解引用空指针则会引发bad_typeid异常!

  • typeid 返回type_info引用
const std::type_info& tinforef = typeid( int ); //编译通过
const std::type_info tinfo = typeid( int );     //编译错误

type_info类型具有私有的拷贝构造函数和赋值函数,因此typeid返回的引用不能被赋给type_info对象,同样type_info也没有公有构造函数因此不能被创建,只能通过这种引用的方式获取它的实例!

  • type_info 声明
class type_info {
public:
    virtual ~type_info();
    bool operator==(const type_info& rhs) const noexcept;
    bool operator!=(const type_info& rhs) const noexcept;
    bool before(const type_info& rhs) const noexcept;
    size_t hash_code() const noexcept;
    const char* name() const noexcept;
private:
    type_info(const type_info& rhs);
    type_info& operator=(const type_info& rhs);
};

这里的”==”判断类型是否一样,而不是判定两个指针指向同一个对象。

const std::type_info& tinforef = typeid( Employee ); 
Employee employee;
Person* ptr = &employee;
if( tinforef == typeid( *ptr ) ) //判断成立,都是Employee类型
{...}

dynamic_cast

作为 RTTI 三大件之一, dynamic_cast可能是最重要的了!前面我们已经讲过了dynamic_cast的用法,而且也指出dynamic_cast必须是作用于多态类型,下面的代码会编译错误, 因为Person没有虚函数不是多态类型!

class Person {};
class Employee : public Person {};
Employee employee;
Person* ptr = &employee;
Employee* emp = dynamic_cast<Employee*>(ptr);

RTTI 实现模型

关于RTTI到底怎么实现,标准没有指出,因此不同的编译器有不同的实现方法。这里为了便于理解RTTI的运行原理给出了一个实现模型!
这里编译器在vtable里面添加了一项type_info*指针,指向type_info结构,每个类型有一个type_info数据段。 从这里可以看出编译器提供关闭RTTI选项的作用了,由于编译器需要为每个多态类型产生一个type_info结构,关闭RTTI确实可以省出不少空间!
这里写图片描述


RTTI 的消耗

RTTI的消耗到底是多少,具体的情况肯定取决于编译器的实现和实际的类型,比如类型名的长度等等。


编译器选项

Visual Studio 和 GCC 默认都打开RTTI支持,但是你也可以关闭该选项,在Visual Studio下,Properties->Configuration Properties->C/C++->Language,右面Enable Run-Time Type Information选择No(/GR-). GCC使用-fno-rtti关闭RTTI支持。

此时使用dynamic_cast,typeid都会抛出std::__non_rtti_object异常!显然这是因为这时候编译器并没有为多态类型生成type_info数据,而dynamic_cast,typeid都会用到这一信息!

需要注意的是关闭了RTTI 并不一定导致运行时异常,只有在切实需要type_info信息而RTTI又关闭的时候才会抛出异常。 比如上行转化的时候即使使用了dynamic_cast且关闭了RTTI仍然不会有问题!

运行时类型信息(RTTI) 在C++中,RTTI可以通过运算符进行安全的类型转换,并可以通过typeid运算符和类在运行时操作类型信息。在Object Pascal中,RTTI可以通过as运算符进行安全的类型转换,使用is等类)。在Ada中,带标签的类型对象也存储类型标签,这允许在运行时识别这些对象的类型。in运算符可以在运行时测试对象是否属于特定类型并安全地转换。RTTI仅适用于多态类,即包含至少一个虚方法的类。在实践中,这并不构成限制,因为基类必须具有虚析构函数,以便从基类指针删除派生类对象时可以执行正确的清理操作。 阅读详情

相关推荐

wxWidgets:运行时类型信息 (RTTI)

wxWidgets:运行时类型信息 (RTTI)wxWidgets:运行时类型信息 (RTTI)类信息RTTI例子 wxWidgets:运行时类型信息 (RTTI) C++ 的一个缺点曾经是没有提供关于类及其在继承层次结构中的位置的运行时信息。 另一个仍然存在的问题是,不能仅通过知道类的名称来创建类的实例,这使得诸如持久存储之类的设施难以实现。 大多数 C++ GUI 框架通过一组宏和函数克服了这些限制,wxWidgets 也不例外。由于它起源于将 RTTI 添加到 C++ 标准之前,并且由于一些(尽管是旧

希望我的博客,能帮上你解决学习中工作中所遇到的问题 642

运行时类型信息

RTTI(在运行时,识别一个对象的类型)可以在程序运行时发现和使用类型信息,这就打破了只能在编译期执行面向类型的操作的限制。使用它,可以查询某个Shape引用所指向的对象的确切类型,然后选择或者剔除特例。在面向对象编程中,一般让代码只操纵对基类的引用。在Java中,所有的类型转换都是在运行时进行正确性检查的。

达文的博客 1823

wxWidgets:掌握运行时类型信息RTTI

我们可以使用typeid运算符来检查对象的类型,使用dynamic_cast运算符将基类指针转换为派生类指针,还可以使用wxDynamicCast和wxStaticCast模板进行类型安全检查。上述代码中,我们首先将一个Dog对象赋值给一个Animal指针(这是合法的,因为Dog是Animal的派生类)。在wxWidgets中,所有的类都具有至少一个虚拟函数,所以我们可以使用typeid来检查任何wxWidgets对象的类型。首先,在wxWidgets中,可以使用typeid运算符来获取一个对象的类型。

带你成为别人眼中的大佬! 206

vs项目配置

定义源文件的预处理符号,其实就是定义了一些。

顺其自然~专栏 1万+

Arduino——GY39大气压、温湿度、光照模块

前几天买东西的时候买了一个GY39,这个模块集成了温湿度,大气压,海拔,光照一体,使用起来很方面。它有两种工作模式使用串口模式时需要搭配转接板,我选择了IIC模式,看一下通信协议吧,就是关于高八位和低八位的数据。看一下接线。

戚晨夕的博客 2604

车底盘:阿克曼转向和四轮差速

特性四轮差速四轮转向阿克曼转向转向方式控制左右轮组速度差控制四个轮子的角度控制前轮角度(后轮固定)运动原理滑移摩擦(搓着走)纯滚动(滚着走)近乎纯滚动(低速时)能耗高低(实现纯滚动时)中轮胎磨损非常严重小中灵活性高(可原地旋转)极高(可全向移动)低(转弯半径大)控制精度较低(受地面摩擦影响大)极高高机械复杂度低(通常只需2个驱动电机)极高(需4个转向+4个驱动执行器)中(需1个转向+2个驱动执行器)典型应用坦克、履带车辆、简单AGV、扫地机器人豪华轿车、高性能全向AGV。

bing_feilong的博客 1920

C++由于指针对象释放,造成Std::__non_rtti_Object例外发生

在实际编程中,我们经常会遇到下面的情景: class A { A(); virtual ~A(); } class B : public A { B(); virtual ~B(); } void main() { B* pB = new B(); B* ppB = pB; dele...

keenKang的专栏 3235

【实用教程】使用AlphaFold2进行蛋白质结构在线预测

使用Colab进行简单快速的AlphaFold2在线的蛋白质三维结构预测

Eumenidus的博客 14万+

[面试] C/C++ 语法(六)—— RTTI(运行时类型信息)

RTTI(RunTime Type Information),顾名思义,对象运行时类型信息,以便在运行时进行类型识别。C++ 的对象识别可通过以下三个技术得以实现: (1)dynamic_cast 运算符(类型安全的向下转型)向下转型是不安全的,多态基类指针转换派生类指针时是类型安全的; (2)typeid 运算符 (3)type_info class Shape { public: vir

2052

别再为格式发愁:safetensors转GGUF的三种高效方法及Ollama集成对比

本文详细介绍了将safetensors格式转换为GGUF格式的三种高效方法,包括llama.cpp原生转换、GGUF官方工具链和Transformers中转方案,并对比了它们在Ollama集成中的表现。文章还提供了实际项目中的踩坑经验和性能调优建议,帮助开发者快速掌握模型转换技术。

weixin_42651281的博客 640

别再死记硬背了!一张图搞懂无刷电机半桥与全桥驱动的核心差异(附避坑指南)

本文深入解析无刷直流电机的半桥与全桥驱动方式的核心差异,提供直观对比与选型指南。半桥驱动结构简单、成本低,适合低要求场景;全桥驱动性能优越但复杂,适用于高精度控制。文章还包含实战避坑指南,帮助工程师优化驱动方案选择与应用。

weixin_29290947的博客 319

RTTI(运行时类型信息)

RTTI 是 “Run-Time Type Information”(运行时类型信息)的缩写。它是 C++ 提供的一种机制,用于在运行时获取和操作对象的类型信息。C++ 是一种静态类型语言,这意味着在编译时大部分类型信息是已知的。然而,有些情况下,我们需要在运行时动态地获取对象的类型信息,以便进行类型检查、类型转换和多态操作等。RTTI 是通过在对象的内存布局中添加额外的元数据信息来实现的。因此,它会增加对象的存储空间和运行时开销。

小木子先生的博客 779

LobeHub开源AI应用平台:从部署到定制的全栈实践指南

在现代AI应用开发领域,大语言模型(LLM)的集成与部署是核心技术挑战之一。其原理在于通过API或本地化部署,将预训练模型的强大能力封装为可调用的服务。这项技术的核心价值在于极大地降低了AI应用的开发门槛,使开发者能够快速构建智能对话、内容生成等场景的应用。随着模型即服务(MaaS)模式的普及,一个关键痛点是如何高效地管理多模型、设计友好的用户界面并实现功能扩展。这正是开源项目LobeHub所聚焦的领域,它通过提供可插拔的架构和配置驱动的低代码理念,解决了AI能力落地的“最后一公里”问题。本文将结合Dock

weixin_27210125的博客 750

C++ RTTI 运行时类型信息

TOCTOC。

gopher9511的博客 488

奈曼-皮尔逊准则

奈曼-皮尔逊准则 如果各个假设的先验概率P(Hi)(i=0,1)P(H_i)(i=0,1)P(Hi​)(i=0,1)已知,并且每种判决的代价函数已知,这时,可以用贝叶斯准则进行判决。 如果进一步假设正确判决不付出的代价,而错误判决代价相同,即c00=c11=0,c01=c10=1c_{00}=c_{11}=0,c_{01}=c_{10}=1c00​=c11​=0,c01​=c10​=1,这时可以用最小平均错误概率准则进行判决。 在不知道先验概率P(Hi)(i=0,1)P(H_i)(i=0,1)P(Hi​)(

little_soldier的专栏 1万+

Ultralytics 框架中predict 与 track 的区别

在 Ultralytics 框架中,predict 和 track 是两种不同的推理方法,分别用于目标检测(或分割、姿态估计)和目标跟踪任务。

浩瀚之水的专栏 1126

C++之运行时类型信息(RTTI)

运行时类型信息RTTI(run time type identification)就两个:typeid和dynamic_cast。其类型信息来自于运行时,所以这两个主要应用于实现多态的父子类之间。一、typeidtypeid是一种运算符,可以获得变量包括对象的类型,作为一个获取运行时类型信息的运算符,目的并不是获取普通变量的类型,而是对象指针的类型。#include<iostream> #inclu

maoliran的博客 1167

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Java运行时类型信息RTTI

应用程序在运行的时候获取一个对象的类型信息的技术称之为运行时类型信息RTTI(Run-Time Type Identification)。RTTI是C++的一个概念,Java中的RTTI是在《think in java》这本书中作者提出来的,官方文档里面并没有RTTI这个概念。作为学习者不应该纠结于一项技术的命名,而应该关注命名所指代的具体技术或者思想,RTTI指代的是一组在运行时获取对象类型信息...

烧水匠 252

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

理解 RTTI:运行时类型信息

RTTI 允许程序在运行时检查对象的类型信息。在 C++ 中,这个机制主要通过typeid操作符和运算符来实现。RTTI 的存在使得程序能够在运行时了解对象的实际类型,这对于一些复杂的类层次结构和动态类型处理非常重要。RTTI 是 C++ 中一个强大且有用的特性,提供了在运行时处理对象类型的能力。通过typeid和,程序员可以实现安全的类型转换和类型检查。然而,RTTI 也带来了一些性能和内存开销,使用时需要权衡其优缺点。

li_peixiansang的博客 605

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

RTTI 运行时类型信息

转载自: http://www.vckbase.com/document/viewdoc/?id=653如何在运行时确定对象类型(RTTI)作者:NorthTibet    RTTI 是“Runtime Type Information”的缩写,意思是:运行时类型信息。它提供了运行时确定对象类型的方法。本文将简略介绍 RTTI 的一些背景知识、描述 RTTI 的概念,并通过具体例子和代码介

miyunhong的专栏 840

C++---运行时类型信息(Run-Time Type Information,RTTI)

C++的RTTI(运行时类型信息)机制允许在运行时获取对象的实际类型信息,主要通过dynamic_cast和typeid实现。dynamic_cast用于安全向下转型,在继承层次中进行类型转换;typeid返回类型标识用于类型比较。RTTI底层依赖虚函数表,仅适用于多态类。虽然RTTI能解决基类接口无法覆盖派生类特有操作的问题,但存在性能开销和破坏封装性的风险,应谨慎使用,优先考虑虚函数实现多态。主要适用于类型特定操作、序列化、插件系统等场景。

MzKyle的博客 1064

C++运行时类型信息 (RTTI)

RTTI是”Runtime Type Information”的缩写,意思是运行时类型信息,它提供了运行时确定对象类型的方法。RTTI并不是什么新的东西,很早就有了这个技术,但是,在实际应用中使用的比较少而已。而我这里就是对RTTI进行总结,今天我没有用到,并不代表这个东西没用。学无止境,先从typeid函数开始讲起。

人无远虑,必有近忧 1039

ESP-IDF RTTI:运行时类型信息应用

运行时类型信息(Runtime Type Information,RTTI)是C++语言中一个强大的特性,它允许程序在运行时获取对象的类型信息并进行类型安全的转换。在ESP-IDF(Espressif IoT Development Framework)中,RTTI功能默认是禁用的,但可以通过配置选项启用,为嵌入式开发提供更灵活的面向对象编程能力。 ## RTTI核心组件 ### 1. typ...

gitblog_00782的博客 981

cmake-examples RTTI支持:运行时类型信息配置指南

在C++项目开发中,**RTTI(Runtime Type Information,运行时类型信息)** 是一个重要的语言特性,它允许程序在运行时获取对象的类型信息。对于需要动态类型检查、安全转换和反射功能的项目来说,正确配置RTTI支持至关重要。本文将为您提供完整的CMake RTTI配置指南,帮助您轻松掌握这一关键技术。 RTTI功能包括`dynamic_cast`、`typeid`和`ty

gitblog_00026的博客 470

Delphi中的RTTI:解锁运行时类型信息的奥秘

在Delphi编程中,RTTI(Run-Time Type Information,运行时类型信息)是一项强大的功能,它允许开发者在程序运行期间获取类型信息。本文详细介绍了Delphi中的RTTI机制,包括其工作原理、如何获取类和数据类型的RTTI信息,以及RTTI在实际编程中的应用场景。随着Delphi语言的不断发展,RTTI机制也将继续进化,提供更多的特性和改进,以满足开发者对于运行时类型信息处理的需求。Delphi中的RTTI主要分为类(class)的RTTI和一般数据类型的RTTI。

2401_85763803的博客 922
上一篇: 关于CLASSPATH的一点感想
下一篇: Sorting - heap sort
小马识图
博客等级 码龄18年 8粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值