29. RTTI机制

一、什么是RTTI机制

  C++ 是一种静态类型语言。其数据类型是在编译期就确定的,不能在运行时更改。然而由于面向对象程序设计中多态性的要求,C++ 中的指针或引用(Reference)本身的类型,可能与它实际代表(指向或引用)的类型并不一致。有时我们需要将一个多态指针转换为其实际指向对象的类型,就需要知道运行时的类型信息,这就产生了运行时类型识别的要求。

  RTTI(Run-Time Type Information,运行时类型信息)是 C++ 中的一种机制,它允许程序在运行时确定对象的类型。RTTI 主要通过两个操作符实现:typeiddynamic_cast

  • typeid 操作符:typeid 操作符用于返回表达式的类型信息。它返回一个 std::type_info 对象的引用,该对象包含有关类型的名称和其他信息。typeid 可以用于任何类型的表达式,包括类类型和内置类型。
  • dynamic_cast 操作符 : dynamic_cast 是一个用于处理对象指针或引用的安全向下转型操作符。它允许在运行时检查类型兼容性,并将指向基类的指针或引用安全地转换为指向派生类的指针或引用。

  需要注意的是,RTTI 机制会增加程序的运行时开销,因为它需要在运行时维护类型信息。此外,RTTI 可能会导致设计上的问题,因为它鼓励依赖于类型而不是接口的编程风格。因此,在使用 RTTI 时应该谨慎,并确保它确实是你解决问题的最佳方式。

二、typeid操作符的使用

  在 C++ 中,typeid 是一个操作符,它用于获取表达式的类型信息。typeid 操作符返回一个 std::type_info 类型的对象,该对象包含了关于表达式的类型的详细信息,如类型的名字。typeid 可以用于任何类型的表达式,包括类类型和内置类型。

class Animal 
{
private:string name;public:Animal(void);Animal(string name);virtual void sound(void) = 0;string getName(void);void setName(string name);
};Animal::Animal(void) : name("") {}
Animal::Animal(string name) : name(name) {}string Animal::getName(void)
{return name;
}void Animal::setName(string name)
{this->name = name;
}
class Cat : public Animal
{
public:// 使用父类的构造函数using Animal::Animal;void sound(void) override;
};void Cat::sound(void)
{cout << getName()  << "在叫:喵喵喵" << endl;
}
class Dog : public Animal
{
public:// 使用父类的构造函数using Animal::Animal;void sound(void) override;
};void Dog::sound(void)
{cout << getName()  << "在叫:汪汪汪" << endl;
}
int main(void)
{Animal *cat = new Cat("汤姆");Animal *dog = new Dog("斯派克");Animal *animal = cat;cout << typeid(animal).name() << endl;cout << typeid(*animal).name() << endl;animal = dog;cout << typeid(animal).name() << endl;cout << typeid(*animal).name() << endl;delete cat;delete dog;return 0;
}

  在这个例子中,typeid(animal) 返回的是指针 animal 的类型,而 typeid(*animal) 返回的是 animal 指向的对象的类型。由于 Animal 类有一个虚析构函数,typeid(*animal) 能够在运行时确定对象的实际类型。

  需要注意的是,typeid 对于具有多态性质的类(即具有虚函数的类)能够提供更准确的类型信息。对于没有虚函数的类,typeid 可能只能提供基类的类型信息,而不是实际对象的类型。此外,typeid 的性能开销应该考虑,因为它涉及到运行时类型检查。

三、dynamic_cast操作符的使用

  在 C++ 中,dynamic_cast 是一个操作符,用于在运行时将对象指针或引用安全地转换为目标类型的指针或引用。这种转换通常用于处理继承和多态的情况,尤其是在需要向下转型(从基类指针或引用转型为派生类指针或引用)时。

  dynamic_cast 的主要特点是可以检查转换的合法性,如果转换是不合法的(例如,将一个基类指针转换为一个与之不相关的派生类指针),dynamic_cast 将返回 nullptr(对于指针类型)或者抛出一个 std::bad_cast 异常(对于引用类型)。

  使用 dynamic_cast 需要满足以下条件:

  1. 基类必须至少有一个虚函数,这样编译器才会为基类生成类型信息。
  2. 转换的目标类型必须是类的指针或引用。

  在 Cat 类中新增一个捉老鼠的方法。

class Cat : public Animal
{
public:// 使用父类的构造函数using Animal::Animal;void sound(void) override;void catchMouse(void);
};void Cat::sound(void)
{cout << getName()  << "在叫:喵喵喵" << endl;
}void Cat::catchMouse(void)
{cout << getName()  << "在抓老鼠" << endl;
}
int main(void)
{Animal *animal = new Cat("汤姆");Cat *cat = dynamic_cast<Cat *>(animal);if (cat != nullptr){cat->catchMouse();}delete animal;return 0;
}

  在这个例子中,我们创建了一个 Cat 类型的对象,并通过基类指针 animal 来引用它。使用 dynamic_castanimal 转换为 Cat* 类型的指针 cat。由于 animal 实际上指向的是一个 Cat 对象,所以转换成功,并且我们可以通过 cat 调用 Cat 类的特有的成员函数。

  如果尝试将一个基类指针转换为不相关的派生类指针,dynamic_cast 将失败,返回 nullptr

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

Redis中的String数据类型及相关命令

[经典面试题] redis虽然是单线程模型&#xff0c;为什么效率还这么高&#xff1f;速度这么快呢&#xff1f; 原因&#xff1a;1、redis主要访问内存&#xff0c;数据库则是主要访问硬盘。 2、redis的核心功能&#xff0c;比数据库的核心功能更简单。数据库对于数据的CRUD&…

远程管理不再难!树莓派5安装Raspberry Pi OS并实现使用VNC异地连接

前言&#xff1a;大家好&#xff01;今天我要教你们如何在树莓派5上安装Raspberry Pi OS&#xff0c;并配置SSH和VNC权限。通过这些步骤&#xff0c;你将能够在Windows电脑上使用VNC Viewer&#xff0c;结合Cpolar内网穿透工具&#xff0c;实现长期的公网远程访问管理本地树莓派…

本地部署 Chat Nio

本地部署 Chat Nio 0. 引言1. 本地部署2. 访问 Chat Nio3. 渠道设置4. 聊天 0. 引言 Chat Nio 的功能&#xff1a; &#x1f916;️ 丰富模型支持: 多模型服务商支持 (OpenAI / Anthropic / Gemini / Midjourney 等十余种格式兼容 & 私有化 LLM 支持)&#x1f92f; 美观 …

C# OpenCV 通过高度图去筛选轮廓

//输入图像 threshCropMap.ImWrite("D:\\test\\threshCropMap_BeforeFilterByBlob.bmp"); //设定我们要筛选的高度 var ResultHeight 60; //创建对应高度的图像&#xff0c;由于是高度信息图&#xff0c;所有要使用32位来存放数据 Mat mat new Mat(filter.Rows, fi…

23.UE5删除存档

2-25 删除存档制作_哔哩哔哩_bilibili 按照自己的风格制作删除按钮 这样该行的存档就被从存档列表中删除了&#xff0c;并且实际存档&#xff08;我的存档蓝图&#xff09;中也被删除了 但是存在一个问题&#xff0c;如果存档数据中存在索引为: 0 1 2 3的存档&#xff0c;当索…

【graphics】图形绘制 C++

众所周知&#xff0c;周知所众&#xff0c;图形绘制对于竞赛学僧毫无用处&#xff0c;所以这个文章&#xff0c;专门对相关人员教学&#xff08;成长中的码农、高中僧、大学僧&#xff09;。 他人经验教学参考https://blog.csdn.net/qq_46107892/article/details/133386358?o…

kafka基础

文章目录 一、Kafka入门1.1、JMS1.2、生产者-消费者模式1.3、ZooKeeper 二、kafka基础架构2.1、producer2.2、kafka cluster2.2.1、broker2.2.2、Controller2.2.3、Topic2.2.4、Partition2.2.5、Replication2.2.6、Leader & Follower 2.3、consumer 一、Kafka入门 Kafka是一…

PMP–一、二、三模、冲刺–分类--5.范围管理--技巧--需求跟踪矩阵

文章目录 技巧一模反例不选“需求跟踪矩阵”4.整合管理86、 [单选] 项目经理加入一个项目&#xff0c;但项目经理在该项目所涉及的行业经验有限&#xff0c;在该项目的整个生命周期中&#xff0c;项目经理精心记录每个差距、问题和不一致性。但是&#xff0c;无论项目经理如何记…

掌握Golang中的数据竞争检测:runtime/race包全面教程

掌握Golang中的数据竞争检测&#xff1a;runtime/race包全面教程 引言数据竞争问题概述数据竞争的定义数据竞争对程序的影响常见数据竞争场景 Golang runtime/race包概述runtime/race包简介启用数据竞争检测使用 go run使用 go build使用 go test 基本用法与示例单元测试中的使…

ThreadLocal父子线程、线程池数据传递解决

多线程并发数据访问&#xff0c;确保数据安全至关重要&#xff0c;常用保证数据安全的方法有对代码synchronized锁、Lock锁&#xff0c;以及基于CAS的原子类&#xff0c;这些都是通过数据共享保障数据安全的&#xff0c;今天聊一聊另一种方案ThreadLocal线程副本&#xff0c;实…

Docker 从入门到精通全攻略

一、Docker 初印象 Docker 诞生于 2013 年&#xff0c;由 dotCloud 公司发起&#xff0c;最初是一个公司内部项目。其诞生背景源于程序员们苦于应用部署环境的复杂性&#xff0c;开发、测试、部署过程中各种库的依赖纷繁复杂&#xff0c;版本差异以及测试环境与部署环境不一致等…

WordPress设置自动更新CSS版本号

WordPress 通常会在引用 CSS 文件时添加版本号参数&#xff08;?verx.x.x&#xff09;。如果版本号未更新&#xff0c;浏览器可能继续加载旧的文件。 解决方法&#xff1a;确保你在 functions.php 文件中正确加载了 CSS 文件&#xff0c;并动态更新版本号。例如在functions.p…

达梦 DG

监视器 switchover 关于达梦DG switchover的细节&#xff0c;以下是一些关键步骤和注意事项&#xff1a; • 切换前检查确认&#xff1a; • 确认数据库版本和DG架构&#xff0c;包括IP信息及切换角色前后的情况。 • 检查DG切换方式&#xff0c;是switch over还是fail ove…

c#基本数据类型占用字节长度/取值范围/对应.net类型

具体前往&#xff1a;c#基本数据类型占用字节数/取值范围/包装类-各基本类型.net类型,占用bit位数,默认值及取值范围

多品牌NVR管理工具/设备EasyNVR多个NVR同时管理支持RTSP接入

在当今数字化浪潮席卷全球的背景下&#xff0c;视频监控行业正经历着前所未有的变革。传统的本地录像存储模式正逐步向云端集中管理转型&#xff0c;这一技术的飞跃不仅极大地提升了监控效率与安全性&#xff0c;更为各行各业的智能化管理开辟了新路径。在这一转型过程中&#…

初学者指南:知识库问答(KBQA)多跳路径的核心与应用

初学者指南&#xff1a;知识库问答&#xff08;KBQA&#xff09;多跳路径的核心与应用 知识库问答&#xff08;Knowledge Base Question Answering, KBQA&#xff09;旨在利用结构化知识库&#xff08;如Wikidata、Freebase&#xff09;回答自然语言问题。在实际应用中&#x…

利用Python爬虫获取淘宝店铺详情

在数字化时代&#xff0c;数据已成为企业最宝贵的资产之一。对于电商平台&#xff0c;尤其是淘宝这样的大型电商平台&#xff0c;店铺详情数据的获取和分析对于商家来说至关重要。它不仅可以帮助商家了解市场趋势&#xff0c;还可以优化营销策略&#xff0c;提升销售业绩。本文…

卡尔曼滤波学习资料汇总

卡尔曼滤波学习资料汇总 其实&#xff0c;当初的目的&#xff0c;是为了写 MPU6050 的代码的&#xff0c;然后不知不觉学了那么多&#xff0c;也是因为好奇、感兴趣吧 有些还没看完&#xff0c;之后笔记也会同步更新的 学习原始材料 【卡尔曼滤波器】1_递归算法_Recursive P…

【HCIP]——OSPF综合实验

题目 实验需求 根据上图可得&#xff0c;实验需求为&#xff1a; 1.R5作为ISP&#xff1a;其上只能配置IP地址&#xff1b;R4作为企业边界路由器&#xff0c;出口公网地址需要通过PPP协议获取&#xff0c;并进行CHAP认证。&#xff08;PS&#xff1a;因PPP协议尚未学习&#…

MarkDown笔记记录app——待更新

1&#xff0c;语雀&#xff1a; 容易整理&#xff0c;直接上手&#xff0c;直接导出到csdn或者是github中 2&#xff0c;notion&#xff1a;注意及时清理 平时主要资料整理部分&#xff0c;注意每个page里面包含子page不能超过5MB&#xff0c; 所有的老资料笔记需要导出为htm…