RTTI简述

2023-11-18


RTTI的用途

  得益于虚函数表,如果派生类实现了基类中的虚函数,通过基类指针或引用可以完成正确的函数调用。

  但是也不得不考虑另外一种情况:如果某个派生类中实现了基类定义的虚函数以外的函数,此时,只有基类指针或引用,那么该怎样确认其是正确的派生类类型,从而完成派生类独有函数的调用呢?基于这种情形,因此C++提供了RTTI。

RTTI的使用

  目前C++支持RTTI元素包括:dynamic_cast和typeid(type_info)。

dynamic_cast

  dynamic_cast是最常用的RTTi组件,它解决的是“能否安全的把对象的地址赋给特定类型指针”的问题。我们知道,如果将一个指向派生类的对象赋值给派生类指针或基类指针都是没有问题的,但是如果将基类对象赋值给派生类指针就没有那么安全了,因为基类中并不包含派生类中可能存在的一些独有的数据成员或方法。

  通过dynamic_cast,我们可以解决这个问题,示例如下:

class Grand{}
class Superb : public Grand{}
class Magnificent : public Superb{ void say(){} }

Grand *pg = new Grand;
Superb * ps  = dynamic_cast<Superb *>(pg);

  针对上面的示例而言:如果pg 的类型可被安全地转换为Superb *,那么返回对象地址,否则返回一个空指针。

typeid

  typeid可以确定两个对象是否是同种类型,它可以接收两种参数:类名、结果为对象地表达式。

  typeid运算符返回一个对type_info对象地引用,type_info重载了 == 和 != 运算符,以便可以使用这些运算符对类型进行比较,示例如下:

typeid(Magnificent) == typeid(*pg)
cout() << typeid(*pg).name();  //返回类型名

  如果pg是一个空指针,程序将会引发bad_typeid异常。

使用总结

  如下提供了上述两者在实际使用时对比:

Grand *pg ...;  //Grand、Superb 、Magnificent 都有可能
Magnificent *pm;
if(pm  = dynamic_cast<Magnificent *>(pg))
	pm->say();
if(typeid(Magnificent) == typeid(*pg))
	pm = (Magnificent *)pg;
	pm->say();

  从上述代码可以看出,dynamic_cast使用起来比typeid更简洁,所以大多数情况下,我们应当将dynamic_cast作为首选。

dynamic_cast与其他转换运算符

  • dynamic_cast:用于类层次结构中的向上转换,这种类型转换是安全的,不允许其他转换。
  • const_cast:将const类型转换为非const类型。
  • static_cast:当一种类型可被隐式转换为其他类型时,这种转换才是合法的,否则将出错。支持的转换包括向上转换、向下转换、基本类型的转换。
  • reinterpret_cast:适用于依赖于实现的底层编程技术,不可移植,用到的情形较少,了解即可。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RTTI简述 的相关文章

  • Asp.net core默认路由

    简化版Startup code public void ConfigureServices IServiceCollection services services AddMvc public void Configure IApplica
  • 从实体获取单列

    如何从查询中获取单个列而不是整个对象 我可以这样做来获取整个对象 但我想要的只是名称 IList
  • 在 Web 浏览器中禁用 F5 [重复]

    这个问题在这里已经有答案了 可能的重复 禁用浏览器的后退按钮 https stackoverflow com questions 961188 disable browsers back button 如何禁用浏览器上的 F5 刷新 htt
  • 从另一个 FORM 中取回隐藏的 FORM

    我有两种形式Form1 and Form2 我正在打开Form2 from Form1 on button Click Form2 obj2 new Form2 this Visible false obj2 Show 然后我想回来Form
  • 如何调整 Windows 窗体以适应任何屏幕分辨率?

    我知道这是重复的问题 但我检查了所有其他相关问题 他们的答案没有帮助 结果仍然与屏幕截图 2 中所示相同 我是 C Windows 窗体新手 如截图1所示 我有Form1有一些控件 每组控件都放在一个面板中 我在 PC1 中设计了应用程序
  • C++中的类要具备什么条件才能成为容器?

    我是 C 编程新手 偶然发现了这个术语containers举例如下vector deque map etc 一个企业的最低要求应该是什么class应该满足被称为container in C 我将从 范围 这个概念开始 Range 只有两个方
  • 具有多个谓词的 C++11 算法

    功能如std find if来自algorithmheader 确实很有用 但对我来说 一个严重的限制是我只能为每次调用使用 1 个谓词count if 例如给定一个像这样的容器std vector我想同时应用相同的迭代find if 多个
  • 名称查找、实例化点 (POI) 和基本类型

    以下代码针对 X 进行编译 但不适用于 double struct X void foo double void foo X namespace NN struct A void foo A foo double error foo not
  • 如何增加ofstream的缓冲区大小

    我想增加 C 程序的缓冲区大小 以便它不会过于频繁地写入 默认缓冲区是 8192 字节 我尝试使用 pubsetbuf 将其增加到 200K 原始代码 ofstream fq fastq1 cstr ios out fastq1 is a
  • 如何设置消息队列的所有者?

    System Messaging MessageQueue 类不提供设置队列所有权的方法 如何以编程方式设置 MSMQ 消息队列的所有者 简短的答案是 p invoke 对 windows api 函数的调用MQSetQueueSecuri
  • MSChart 控件中的自定义 X/Y 网格线

    我有一个带有简单 2D 折线图的 C Windows 窗体 我想向其中添加自定义 X 或 Y 轴标记 并绘制自定义网格线 例如 以突出显示的颜色 虚线 我查看了 customLabels 属性 但这似乎覆盖了我仍然想显示的默认网格 这是为了
  • 在 C++ 代码 gdb 中回溯指针

    我在运行 C 应用程序时遇到段错误 在 gdb 中 它显示我的一个指针位置已损坏 但我在应用程序期间创建了 10 万个这样的对象指针 我怎样才能看到导致崩溃的一个 我可以在 bt 命令中执行任何操作来查看该指针的生命周期吗 谢谢 鲁奇 据我
  • WinForms - 加载表单时如何使用 PaintEventArgs 运行函数?

    我试图理解图形 在 Graphics FromImage 文档中 它有这样的示例 private void FromImageImage PaintEventArgs e Create image Image imageFile Image
  • C++ 模板可以提供 N 个给定类的公共父类吗?

    我正在寻找一个 C 模板 它可以找到一组给定类的共同父级 例如 class Animal class Mammal public Animal class Fish public Animal class Cat public Mammal
  • WPF DataGrid - 在每行末尾添加按钮

    我想在数据网格的每一行的末尾添加一个按钮 我找到了以下 xaml 但它将按钮添加到开头 有人知道如何在所有数据绑定列之后添加它吗 这会将按钮添加到开头而不是末尾
  • 使用 Unity 在 C# 中发送 http 请求

    如何使用 Unity 在 C 中发送 HTTP GET 和 POST 请求 我想要的是 在post请求中发送json数据 我使用Unity序列化器 所以不需要 新的 我只想在发布数据中传递一个字符串并且能够 将 ContentType 设置
  • 如何测试某些代码在 C++ 中无法编译? [复制]

    这个问题在这里已经有答案了 可能的重复 单元测试编译时错误 https stackoverflow com questions 605915 unit test compile time error 我想知道是否可以编写一种单元测试来验证给
  • 运行 xunit 测试时无法将输出打印到控制台窗口

    public class test2InAnotherProject private readonly ITestOutputHelper output public test2InAnotherProject ITestOutputHel
  • 如何在 Razor 编辑视图中显示选中的单选按钮 Asp net core mvc

    尽管 Razor 视图中的 Asp 网络核心代码 model List
  • 如何在c中断言两个类型相等?

    在 C 中如何断言两种类型相等 在 C 中 我会使用 std is same 但搜索 StackOverflow 和其他地方似乎只能给出 C 和 C 的结果 在C中没有办法做到这一点吗 请注意 这不是询问变量是否具有某种类型 而是询问两个类

随机推荐

  • malloc和strcpy,入门的指针面试题

    指针是C和C 编程语言中一个重要的概念 因此在面试以及工作中经常会涉及到指针相关的问题 现在列举几个比较基础问题 一 void getMemory char p p char malloc 100 void test void char s
  • 【使用Excel批量修改文件名称——超详细教程——无需复杂操作;bat,ren指令】

    基本指令 bat concatenate concatenate 该公式用于给新文件名名称添加后缀 ren公式 ren A2 B2 要注意的是ren后边有一个空格 后边有一个空格 此公式用于合并旧文件与新文件名称 操作步骤 首先创建一个文本
  • C语言 函数 下

    函数的定义 如果函数的定义在main函数之后 函数要在main函数前先进行声明 写一个函数完成两个整数的相加 int Add int a int b 函数的声明 int main printf 请您输入a b的值 int a 0 int b
  • Python入门---初识

    Python简介 Python的历史 1989年圣诞节 Guido von Rossum开始写Python语言的编译器 1991年2月 第一个Python编译器 同时也是解释器 诞生 它是用C语言实现的 后面 可以调用C语言的库函数 在最早
  • python入门教程(非常详细)

    Python是一种高级 解释性的脚本语言 其简单易学 灵活 强大等特点 使其成为了当代最流行的编程语言之一 如果您是想学习Python编程的新手 以下是详细的Python入门教程 以帮助您快速掌握Python编程基础 1 安装Python
  • STM32 基础系列教程 50 – MbedTls

    前言 mbed TLS 以前称为PolarSSL 是TLS和SSL协议的实现 并且需要相应的加密算法和支持代码 这是双重许可与Apache许可证 2 0版 与GPLv2许可也可 网站上指出 mbed TLS的目标是 易于理解 使用 集成和扩
  • 详解 C 语言中的弱符号与弱引用

    C语言中的 attribute weak 与 attribute weakref 引言 最近在看 linux 中一些驱动代码 驱动代码中为了实现程序的扩展性和兼容性用了很多 C 语言中的高级特性 本节就来谈一谈 C 语言中的弱符号和弱引用的
  • 机器学习在工程中使用要点

    机器学习现在有很多分支 大部分使用数据和模型优化入手 在此之前机器学习按照学派划分是有可靠的理论依据的 那么我们使用应该注意以下几点 1 如何获取训练集 一般我们下载现有的训练集为了学习或者来测试自己的算法泛化能力的表现水平 这时候我们对训
  • Java并发问题--乐观锁与悲观锁以及乐观锁的一种实现方式-CAS

    首先介绍一些乐观锁与悲观锁 悲观锁 总是假设最坏的情况 每次去拿数据的时候都认为别人会修改 所以每次在拿数据的时候都会上锁 这样别人想拿这个数据就会阻塞直到它拿到锁 传统的关系型数据库里边就用到了很多这种锁机制 比如行锁 表锁等 读锁 写锁
  • 每日站会是在浪费时间...吗?

    原文链接作者 Mark Levison 又要开站会 实在是浪费时间 打断我的工作啦 每日站会只是为ScrumMaster刷存在感而设计的 便于他微观管理 每日站会上就是汇报一下状态 而我写个邮件就行了啊 你以前听说过这些抱怨吗 我听过 不过
  • Java中获取数组长度

    Java中获取数组长度 方法 使用数组属性length来获取数组长度 代码 public class ArrayLength public static void main String args String data new Strin
  • Linux服务器之间的文件同步(单向同步:rsync+inotify)

    1 rsync简介 rsync是linux系统下的数据备份工具 支持本地复制 或者与其他SSH rsync主机同步 2 rsync的部分特性 rsync支持很多特性 可以镜像保存整个目录树和文件系统 可以很容易做到保持原来文件的权限 时间
  • APICloud(四):图片上传-Java版

    这一篇讲 将选择的图片上传到指定的服务器 说实话 这个功能写了好久 一会儿json拼的有问题访问不到后台 一会儿后台又说form表单的enctype不是multipart form data类型 各种乱七八糟的问题折腾了一下午都没好 第二天
  • 蓝桥杯---貌似化学---逆矩阵

    试题 算法训练 貌似化学 资源限制 时间限制 1 0s 内存限制 256 0MB 问题描述 现在有a b c三种原料 如果他们按x y z混合 就能产生一种神奇的物品d 当然不一定只产生一份d 但a b c的最简比一定是x y z 现在给你
  • 快速识别图像的RGB值

    今天无意发现 使用QQ的文字识别功能也可以识别色彩颜色 ctrl alt o 移动鼠标指针至想要提取颜色的位置 按c键就可以复制色号了 代码里一粘贴直接就是RGB值
  • 线性自抗扰(LADRC)的stm32f1程序,实现用编码器反馈控制直流电机调速,控制器采用加了TD的LADRC

    线性自抗扰 LADRC 的stm32f1程序 实现用编码器反馈控制直流电机调速 控制器采用加了TD的LADRC 控制效果良好 h和 c分开 代码清晰有注释 有调试说明 YID 1235653714412755tbNick 9w978
  • 记一次 微信小程序封装请求方法

    调用 const res await requestMmsq app params 或者 request app then res gt const baby fetus res this setData baby fetus
  • vscode是什么(vscode干嘛用的)

    vscode是什么 接触VSCode不太长 但是我觉得我越来越喜欢它 所以我想写些关于它的东西 vscode 首先介绍一下这东西是什么 当然 这是由M 开发和开源的轻量级IDE 可以免费使用 我这样定义 它和VisualStudio之间的区
  • Youtube ASX Portfolio的视频笔记 What is a Quant? - Financial Quantitative Analyst

    What is a Quant Financial Quantitative Analyst YouTube youtube 上搜 option pricing 很多讲解 Stochastic Calculus的 In this video
  • RTTI简述

    RTTI的用途 RTTI的使用 dynamic cast typeid 使用总结 dynamic cast与其他转换运算符 RTTI的用途 得益于虚函数表 如果派生类实现了基类中的虚函数 通过基类指针或引用可以完成正确的函数调用 但是也不得