手动实现一个RTTI系统
在 C++ 中,RTTI(Runtime Type Information,运行时类型信息)是一组允许程序在运行时获取对象类型信息的机制 。虽然C++通过虚接口的方式提供了良好的抽象,但是对于一个复杂的系统,过于依赖抽象而忽略业务的复杂性,隐藏类的具体运行时信息,往往让业务变得不够灵活,或者大大增加虚接口的代价。
标准 C++ RTTI 的组成
typeid
运算符
可以通过typeid函数获取对象的实际类型信息。其返回值为std::type_info
对象,包含类型名称和对比功能。
Base* obj = new Derived();// 获取静态类型信息(编译时确定)
std::cout << typeid(*obj).name() << std::endl; // 输出 "Derived"(若启用 RTTI)// 类型对比
if (typeid(*obj) == typeid(Derived)) {// 实际类型为 Derived
}
dynamic_cast
C++提供的安全类型转换,安全地将基类指针/引用转为派生类指针/引用。但是要求基类必须有虚函数(即多态类型)。指针类型转换失败返回 nullptr
,引用类型转换失败抛出 std::bad_cast
。
type_info
类
存储类型信息,提供 name()
和 operator==
。只能通过 typeid
获取其实例。
C++标准虽然提供了一些简单的RTTI功能,但是存在一些缺点
dynamic_cast
的运行时类型检查可能影响性能(尤其深继承层次)。type_info::name()
返回的名称是编译器修饰后的(如7Derived
)。dynamic_cast
仅适用于有虚函数的类。- 无法添加自定义类型元数据(如版本号、作者等)
不过,用户可以选择启用或者禁用RTTI功能,如果禁用后,就无法使用上面提到的功能,并且值得强调的时,C++RTTI其实是有点违背C++的Zero over head的设计哲学,开启 RTTI 后,所有多态类会携带一个虚表指针 (vptr
),指向包含 type_info
的虚表。即使开发者完全不使用 RTTI,这一内存开销仍然存在。type_info
对象和类型名称字符串会被编译进程序,增加可执行文件
自定义RTTI系统
针对标准 RTTI 的不足,开发者常实现自定义 RTTI 系统 , RTTI系统实现的原理也非常简单
- 定义一个MetaClass用于表示类的元信息
- 每个类使用一个静态的MetaClass存储该类形的信息
- 实现一些常用的如类型名称,类型转换,类型实例化等接口
如下为手动实现的RTTI系统的一些关键组件
元类(MetaClass)
封装类的类型信息,包括类名、父类元类指针、对象构造函数。
关键方法:
isKindOf
:递归检查当前类是否继承自指定父类。create
:通过绑定的构造函数创建对象。
class MetaClass {
public:MetaClass(std::string name, const MetaClass* pParent, ObjectConstructor cons);bool isKindOf(const MetaClass* pParent) const; // 继承关系检查MetaObject* create(); // 创建对象
private:std::string m_name;const MetaClass* mp_parent;ObjectConstructor m_constructor;
};
模板元类(ConcretMeta)为具体类生成元类实例,自动注册到 MetaClassStore
。这里使用单例的方式来获取类的MetaClass
template <class T>
class ConcretMeta : public MetaClass {
public:static const MetaClass* instance() {static ConcretMeta s_meta;MetaClassStore::instance()->insert(&s_meta);return &s_meta;}
private:ConcretMeta() : MetaClass(T::class_name(), ConcretMeta<T::BaseClass>::instance(), [] { return new T(); }) {}
};
对象基类(MetaObject)
所有需要有RTTI能力的类需要继承自MetaObject,该类定义了获取MetaClass的接口和其他类型转换接口。
class MetaObject
{
public:virtual ~MetaObject() = 0;virtual const MetaClass* meta() const = 0; //called by instancestatic const MetaClass* staic_meta(); //called by classstatic MetaObject* meta_cast(MetaObject* pOther);static std::string class_name();bool isKindOf(const MetaClass* pMeta) const;public:MetaObject() = default;
};
RTTI定义宏系统
DECLARE_META_CLASS
:声明元类接口。DEFINE_META_CLASS
:实现元类绑定和类型转换。
// 声明.h
class MyClass : public MetaObject {DECLARE_META_CLASS(MyClass, MetaObject);
};// 定义.cpp
DEFINE_META_CLASS(MyClass, MetaObject);
该 RTTI 系统通过模板和宏巧妙地将类型信息抽象为运行时对象,实现了类型创建、继承检查和简单反射功能。设计简洁且易于扩展,可作为复杂对象工厂或序列化系统的基础组件。
相关文章:
手动实现一个RTTI系统
在 C 中,RTTI(Runtime Type Information,运行时类型信息)是一组允许程序在运行时获取对象类型信息的机制 。虽然C通过虚接口的方式提供了良好的抽象,但是对于一个复杂的系统,过于依赖抽象而忽略业务的复杂性…...
智能化水利监管:无人机视频在违章行为识别中的应用
随着我国经济社会的快速发展,水利工程建设规模不断扩大,但随之而来的违章建设行为也日益增多。传统的人工巡查方式效率低下,难以满足当前监管需求。无人机技术以其灵活性和高效性,为水利工程建设监管提供了新的解决方案。本文将探…...
力扣练习之确定两个字符串是否接近
目录 题目: 题解: 详细题解 题目: 如果可以使用以下操作从一个字符串得到另一个字符串,则认为两个字符串 接近 : 操作 1:交换任意两个 现有 字符。 例如,abcde -> aecdb 操作 2࿱…...
Word 小黑第21套
对应大猫22 设置表格为页面的80%:表布局 -属性 -表格 指定宽度80% 度量单位改成百分比 段落组 -中文版式 在表格上下方留一行空段(如果表格太大改一下样式)插入横线 边框线 (右击横线 -图片 修改样式) 段落 -取消对于…...
mingw32编译ffmpeg
ffmpeg https://gitee.com/mirrors/ffmpeg.git 使用msys2的mingw32 pacman -S mingw-w64-x86_64-toolchain compile ./confiure --enable-static --disable-shared --enable-gpl --target-oswin32 mingw32-make -j4 提示编译错误,msys2里面的路径是/d/tools/msys2…...
设计模式C++
针对一些经典的常见的场景, 给定了一些对应的解决方案,这个就叫设计模式。 设计模式的作用:使代码的可重用性高,可读性强,灵活性好,可维护性强。 设计原则: 单一职责原则:一个类只做一方面的…...
使用 Excel 实现绩效看板的自动化
引言 在日常工作中,团队的绩效监控和管理是确保项目顺利进行的重要环节。然而,面临着以下问题: 数据分散:系统中的数据难以汇总,缺乏一个宏观的团队执行情况视图。看板缺失:系统本身可能无法提供合适…...
ngx_openssl_conf_t
ngx_openssl_conf_t 定义在 src\event\ngx_event_openssl.c typedef struct {ngx_uint_t engine; /* unsigned engine:1; */ } ngx_openssl_conf_t; 1. 这个结构体的目的是存储与 OpenSSL 引擎相关的配置信息。 2. engine 字段用于标识是否启用 OpenSSL 的硬件加速引擎…...
深度学习环境配置指令大全
文章目录 环境配置官网/博客合集清华镜像站anaconda官网pytorch官网pytorch历史库官网pytorch与cuda对应版本下载博客torch与torchvision与python对应关系python与pytorch对应关系 环境相关创建环境激活环境退出环境删除环境检查环境冲突 安装相关安装requirementsconda安装con…...
Netty启动源码NioEventLoop剖析accept剖析read剖析write剖析
学习链接 NIO&Netty - 专栏 Netty核心技术十–Netty 核心源码剖析Netty核心技术九–TCP 粘包和拆包及解决方案Netty核心技术七–Google ProtobufNetty核心技术六–Netty核心模块组件Netty核心技术五–Netty高性能架构设计 聊聊Netty那些事儿 - 专栏 一文搞懂Netty发送数…...
<03.13>八股文补充知识
import java.lang.reflect.*; public class Main {public static void main(String[] args) throws Exception {// 获取 Class 对象//1. 通过类字面量Class<?> clazz Person.class;//2 通过对象实例化String str "Hello";Class<?> clazz_str str.ge…...
[HUBUCTF 2022 新生赛]messy_traffic
下载附件 看到文件类型直接用wireshark打开,对MySQL协议进行追踪流,并没有什么发现,后面对NO.437发现有用信息,http追踪流 发现**system(‘cat passwd.txt’);**这里是在打开查看passwd.txt,密码是"SignUpForHUBU…...
条款1:理解模版性别推导
目录 问题引出 情况1:ParamType是个指针或引用,但不是个万能引用。 情况2:ParamType是个万能引用 情况3:ParamType既非指针也非引用 问题引出 函数模板大致形如: template<typename T> void f(ParamType p…...
kafka连问
1,kafka多消费者指部署多个服务消费节点吗 2,多个消费节点自动组成消费组吗 3,消费者组与多消费节点关系 4,一个分区,多个消费者,可以保证有序消费吗 5,kafka如何实现顺序消费,一…...
Linux中基础开发工具详细介绍
目录 软件包管理器什么是软件包Linux软件生态 yum具体操作查看软件包安装软件卸载软件注意事项 编辑器VimLinux编辑器-vim使用vim的基本概念快速编辑的指令 编译器gcc/g背景知识gcc编译选项预处理(进行宏替换)编译(生成汇编)汇编(生成机器可识…...
浅谈时钟启动和Systemlnit函数
时钟是STM32的关键,是整个系统的心脏,时钟如何启动,时钟源如何选择,各个参数如何设置,我们从源码来简单分析一下时钟的启动函数Systemlnit()。 Systemlnit函数简介 我们先来看一下源程序的注释…...
社交软件频繁更新,UI 设计在其中扮演什么角色?
在当今数字化时代,社交软件已成为人们日常生活中不可或缺的一部分。随着科技的飞速发展和用户需求的不断变化,社交软件更新频率日益加快。在这频繁更新的背后,UI 设计扮演着至关重要的角色,它如同社交软件的 “门面担当” 与 “交…...
SQLMesh 系列教程:解锁SQLMesh的宏与变量魔法
在数据库流水线开发中,代码复用与动态配置是提升效率的核心诉求。SQLMesh以其独特的宏系统与用户定义变量机制,重新定义了SQL生成的灵活性。与传统模板引擎不同,SQLMesh的宏并非简单的字符串替换,而是基于语义理解的智能代码重构—…...
React篇之three渲染
需求:拖拽右侧面板,里面的three模型能够自适应 import { useEffect, useState, useRef } from react import ./App.css import * as THREE from three; import { GLTFLoader } from three/addons/loaders/GLTFLoader.js; import { debounce } from loda…...
PHP与前端框架的无缝集成:最佳实践与案例分析
PHP与前端框架的无缝集成:最佳实践与案例分析 在现代Web开发中,PHP作为后端语言与前端框架的集成已成为一种常见的开发模式。无论是传统的MVC架构,还是现代的SPA(单页应用),PHP与前端框架的无缝集成能够显…...
Redis内存淘汰策略
Redis 是一种高性能的键值存储系统,广泛用于缓存、消息队列等场景。由于 Redis 数据存储在内存中,而内存资源有限,因此需要内存淘汰策略来管理内存的使用。Redis 提供了多种内存淘汰策略,可以根据不同的应用场景选择合适的策略。 …...
Facebook 的框架及技术栈
一、前端框架与技术 React.js 及其生态系统 核心原理与特点 React.js 是 Facebook 开源的用于构建用户界面的 JavaScript 库。它的核心概念是组件化,将用户界面拆分成一个个独立的、可复用的组件。每个组件都有自己的状态(state)和属性&#…...
QT中的布局管理
在 Qt 中,布局管理器(如 QHBoxLayout 和 QVBoxLayout)的构造函数可以接受一个 QWidget* 参数,用于指定该布局的父控件。如果指定了父控件,布局会自动将其管理的控件添加到父控件中。 在你的代码中,QHBoxLa…...
如何学习VBA_3.2.20:DTP与Datepicker实现日期的输入
我给VBA的定义:VBA是个人小型自动化处理的有效工具。利用好了,可以大大提高自己的劳动效率,而且可以提高数据处理的准确度。我推出的VBA系列教程共九套和一部VBA汉英手册,现在已经全部完成,希望大家利用、学习。 如果…...
在 LaTeX 中强制表格位于页面顶部
在 LaTeX 中强制表格位于页面顶部,可以通过以下 多种方法结合使用,按优先级推荐: 方法 1:使用 [!t] 位置限定符 原理:通过 [!t] 强制 LaTeX 优先将表格放置在页面顶部(Top),! 表示忽…...
dify+mysql的诗词助手
目录 数据库表结构: 数据库查询的http服务搭建: 流程引擎搭建: 开始, HTTP查询数据库, LLM数据分析, 直接回复, 效果测试: 下载链接: 数据库表结构:…...
PyTorch 入门学习
目录 PyTorch 定义 核心作用 应用场景 Pytorch 基本语法 1. 张量的创建 2. 张量的类型转换 3. 张量数值计算 4. 张量运算函数 5. 张量索引操作 6. 张量形状操作 7. 张量拼接操作 8. 自动微分模块 9. 案例-线性回归案例 PyTorch 定义 PyTorch 是一个基于 Python 深…...
【视频】SRS将RTMP转WebRTC、HLS流;获取RTSP转其它流
1、安装依赖库 sudo apt install tclsh sudo apt install cmake sudo apt install autotools-dev automake m4 perl sudo apt install libtool2、源码安装 1)下载源码 https://github.com/ossrs/srs/releases/tag/v5.0-r32)配置、编译 ./configure && make -j83、…...
linux中如何查询文件夹大小
在 Linux 中,可以使用 du 命令查看文件夹大小。以下是常用方法: 标题1. 查看文件夹大小 du -sh /path/to/directory-s:显示总大小。 -h:以易读格式(如 KB、MB、GB)显示大小。 标题2:查看文件…...
MySQL增删改查操作 -- CRUD
个人主页:顾漂亮 目录 1.CRUD简介 2.Create新增 使用示例: 注意点: 3.Retrieve检索 使用示例: 注意点: 4.where条件查询 前置知识:-- 运算符 比较运算符 使用示例: 注意点…...
uniapp+Vue3 组件之间的传值方法
一、父子传值(props / $emit 、ref / $refs) 1、props / $emit 父组件通过 props 向子组件传递数据,子组件通过 $emit 触发事件向父组件传递数据。 父组件: // 父组件中<template><view class"container">…...
TDengine SQL 函数
单行函数 数学函数 ABSACOSASINATANCEILCOSDEGREESEXPFLOORGREATESTLEASTLNLOGMODPIPOWRADIANSRANDROUNDSIGNSINSQRTTANTRUNCATE 字符串函数 ASCIICHARCHAR_LENGTHCONCATCONCAT_WSLENGTHLOWERLTRIMPOSITIONREPEATREPLACERTRIMSUBSTRING/SUBSTRSUBSTRING_INDEXTRIMUPPER 转换函数…...
智能三防手持终端破解传统仓储效率困局
在数字化浪潮的推动下,传统仓储管理模式正面临效率低、成本高、错误频发等瓶颈。如何实现精准、高效、智能化的仓储管理,上海岳冉三防智能手持终端机以RFID技术为核心,结合工业级三防(防水、防摔、防尘)设计࿰…...
力扣——K个一组翻转链表
题目链接: 链接 题目描述: 思路: 可以理解为把原链表的每一段进行反转 把链表的每一段看成新链表,单独进行反转,然后再放回原链表 关键是截取k个节点、进行反转后,怎么再和原链表链接起来 我们把截取的…...
5-27 临摹大师-IP-Adapter
前言: 前一节我们主要介绍ControlNet中如何对黑白照片进行上色 主要介绍ControlNet中的IP-Adapter。这个也是一种类似的风格借鉴,类似Reference的能力。 当然IP-Adapter有两点或许可以吸引我们,一个是国人腾讯公司制作的。另一个在速度和效…...
MinIO的预签名直传机制
我们传统使用MinIo做OSS对象存储的应用方式往往都是在后端配置与MinIO的连接和文件上传下载的相关接口,然后我们在前端调用这些接口完成文件的上传下载机制,但是,当并发量过大,频繁访问会对后端的并发往往会对服务器造成极大的压力…...
树莓科技集团董事长:第五代产业园运营模式的深度剖析与展望
第五代产业园运营模式,以创新为核心驱动,强调数字化、网络化和资源整合。树莓科技集团在这一领域具有代表性,其运营模式值得深入剖析。 核心特征 数字化转型:第五代产业园高度重视数字化技术的应用,通过构建数字化平…...
项目组织管理类型-职能式组织和矩阵式组织的区别
在职能式组织和矩阵式组织中,任务分配和人员安排确实有显著的不同,让我们通过以下例子来进一步解释: 职能式组织在职能式组织中,任务通常是根据部门的职能进行下达的。 例如,一家制造公司的组织结构如下: …...
树莓科技(成都)集团:如何铸就第五代产业园标杆
树莓科技(成都)集团铸就第五代产业园标杆,主要体现在以下几个方面: 精准定位与前瞻布局 树莓科技并非盲目扩张,而是精准锚定数字经济发展方向。以成都为起点,迅速构建起全国性的园区版图,体现…...
【Quest开发】手柄交互震动
软件:Unity 2022.3.51f1c1、vscode、Meta XR All in One SDK V72(要提前导入哦) 硬件:Meta Quest3 参考Meta开发文档:https://developers.meta.com/horizon/documentation/unity/unity-haptics-sdk-integrate 这篇官…...
《Transformer如何进行图像分类:从新手到入门》
引言 如果你对人工智能(AI)或深度学习(Deep Learning)感兴趣,可能听说过“Transformer”这个词。它最初在自然语言处理(NLP)领域大放异彩,比如在翻译、聊天机器人和文本生成中表现出…...
数字图像处理与Python语言实现-Box模糊CUDA实现
Box模糊CUDA实现 文章目录 Box模糊CUDA实现1、Box模糊的基本原理2、算法优化:滑动窗口技术3、参数对模糊效果的影响4、Box模糊的优缺点5、与高斯模糊的对比6、实际应用场景7、算法实现7.1 PyCUDA实现7.2 CuPy实现7.3 C++与CUDA实现8、总结在图像处理领域,**Box模糊(方框模糊…...
MAVEN解决版本依赖冲突
文章目录 一、依赖冲突概念1、什么是依赖冲突2、依赖冲突的原因3、如何解决依赖冲突 二、查看依赖冲突-maven-helper1、安装2、helper使用1、conflicts的阅读顺序(从下向上看)2、dependencies as List的阅读顺序(从下向上看)3、de…...
Compose 实践与探索五 —— AnimationSpec
不论是 animateXxxAsState() 还是 Animatable 的 animateTo() 都可以传入 AnimationSpec 以配置动画的规格: Composable fun animateDpAsState(targetValue: Dp,animationSpec: AnimationSpec<Dp> dpDefaultSpring,label: String "DpAnimation",…...
Embedding模型到底是什么?
嵌入模型(Embedding Model)是一种将高维数据映射到低维空间的工具,广泛应用于自然语言处理(NLP)、推荐系统和图像识别等领域。它的核心目标是将复杂的数据(如文本、图像或用户行为)转换为稠密的…...
数据结构(一)——绪论
一、数据结构的研究内容 1.数据的各种逻辑结构和物理结构,以及他们之间的相应关系 2.存储结构的方法,对每种结构定义相适应的各种运算 3.设计出相应的算法 4.分析算法的效率 二、数据结构的基本概念 1.数据(data):…...
VMware虚拟机网络连接模式介绍以及nat模式访问公网实践
在 VMware 虚拟机中,网络配置是非常重要的一部分。VMware 提供了三种主要的网络连接模式,分别是桥接模式(Bridged)、NAT模式(NAT) 和仅主机模式(Host-Only)。每种模式都有其特定的用…...
Selenium Manager和webdriver manager的区别与联系
一、引言 1.1 自动化测试的重要性 在现代软件开发流程中,自动化测试已经成为保证软件质量和提高交付效率的关键实践。随着软件开发周期的缩短和软件复杂性的增加,手工测试已无法满足快速迭代的需求。自动化测试能够快速、准确地执行重复性测试任务&…...
八叉树地图的原理与实现
八叉树与体素图 八叉树地图 八叉树地图是可变分辨率的三维栅格地图,可以自由调整分辨率,如下所示: 根据点云的数量或密度决定每个叶子方块是否被占据 体素图 体素就是固定分辨率的三维栅格地图,如下所示: 根据点云…...
DeepSeek模型本地化部署方案及Python实现
DeepSeek实在是太火了,虽然经过扩容和调整,但反应依旧不稳定,甚至小圆圈转半天最后却提示“服务器繁忙,请稍后再试。” 故此,本文通过讲解在本地部署 DeepSeek并配合python代码实现,让你零成本搭建自己的AI…...