C++运行时动态类型
RTTI
运行时类型识别(RTTI)的引入有三个作用:
- 配合typeid操作符的实现;
- 实现异常处理中catch的匹配过程;
- 实现动态类型转换dynamic_cast
typeid操作符的实现
静态类型
C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例
#include <typeinfo>
#include <cassert>
struct B {} b, c;
struct D : B {} d;
void test() {
const std::type_info& tb = typeid(b);
const std::type_info& tc = typeid(c);
const std::type_info& td = typeid(d);
assert(tb == tc); // b和c具有相同的类型
assert(&tb == &tc); // tb和tc引用的是相同的对象
assert(tb != td); // 虽然D是B的子类,但是b和d的类型却不同
assert(&tb != &td); // tb和td引用的是不同的对象
}
动态类型
当typeid的操作数引用的是一个动态类(含有虚函数的类) 类型时,它的返回值是被引用对象对应类型的const std::type_info&,例:
#include <typeinfo>
#include <cassert>
struct B { virtual void foo() {} };
struct C { virtual void bar() {} };
struct D : B, C {};
void test() {
D d;
B& rb = d;
C& rc = d;
assert(typeid(rb) == typeid(d)); // rb引用的类型与d相同
assert(typeid(rb) == typeid(rc)); // rb引用的类型与rc引用的类型相同
}
编译时可能还不知道rb或rc引用的类型,运行时怎么能判断该返回基类还是派生类对应的类型信息对象呢?
首先我们看看虚表的结构,在虚函数指针前面有RTTI信息。
如果是含有虚函数,运行时便可以通过vptr找到“虚函数表”,而“虚函数表”之前的一个位置存放了需要的类型信息对象,typeid可以直接返回这里的类型信息对象引用即可。
实现异常处理中catch的匹配过程
catch的匹配过程也可利用与typeid相似的原理进行类型匹配判断,此不再赘述。
动态类型转换(dynamic_cast)
先上一个例子:
type_info对象里面会有整个继承体系的信息(通过指针),因此继承关系可以通过此树状结构判断,有了继承关系,再递归从虚表中查找基类子对象在派生类中的偏移值,便可以确定最终返回地址。
- '# 4例子:
通过pa找到_D的type_info,对比和C的type_info的不同,但是在type_info的指针里面找到C的type_info。加上C的type_info的通过偏移量,返回指针结果 - '# 2例子:
通过pa找到D的type_info,和目标D的type_info相同,直接加上偏移量,返回指针
参考文献
C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理
C++运行时动态类型的更多相关文章
- C# 在运行时动态创建类型
C# 在运行时动态的创建类型,这里是通过动态生成C#源代码,然后通过编译器编译成程序集的方式实现动态创建类型 public static Assembly NewAssembly() { //创建编译 ...
- LINQ to SQL 运行时动态构建查询条件
在进行数据查询时,经常碰到需要动态构建查询条件.使用LINQ实现这个需求可能会比以前拼接SQL语句更麻烦一些.本文介绍了3种运行时动态构建查询条件的方法.本文中的例子最终实现的都是同一个功能,从Nor ...
- 使用javassist运行时动态重新加载java类及其他替换选择
在不少的情况下,我们需要对生产中的系统进行问题排查,但是又不能重启应用,java应用不同于数据库的存储过程,至少到目前为止,还不能原生的支持随时进行编译替换,从这种角度来说,数据库比java的动态性要 ...
- C++高效安全的运行时动态类型转换
关键字:static_cast,dynamic_cast,fast_dynamic_cast,VS 2015. OS:Window 10. C++类之间类型转换有:static_cast.dynami ...
- .NET6运行时动态更新限流阈值
昨天博客园撑不住流量又崩溃了,很巧正在编写这篇文章,于是产生一个假想:如果博客园用上我这个限流组件会怎么样呢? 用户会收到几个429错误,并且多刷新几次就看到了内容,不会出现完全不可用. 还可以降低查 ...
- 运行时动态库:not found 及介绍-linux的-Wl,-rpath命令
---此文章同步自我的CSDN博客--- 一.运行时动态库:not found 今天在使用linux编写c/c++程序时,需要用到第三方的动态库文件.刚开始编译完后,运行提示找不到动态库文件.我就 ...
- Java如何在运行时识别类型信息?
在日常的学习工作当中,有一些知识是我们在读书的时候就能够习得:但有一些知识不是的,需要在实践的时候才能得到真知——这或许就是王阳明提倡的“知行合一”. 在Java中,并不是所有的类型信息都能在编译阶段 ...
- 转: gcc 指定运行时动态库路径
gcc 指定运行时动态库路径 Leave a reply 由于种种原因,Linux 下写 c 代码时要用到一些外部库(不属于标准C的库),可是由于没有权限,无法将这写库安装到系统目录,只好安装用户目录 ...
- [转] Java运行时动态生成class的方法
[From] http://www.liaoxuefeng.com/article/0014617596492474eea2227bf04477e83e6d094683e0536000 廖雪峰 / 编 ...
随机推荐
- ReportMachine OCX
http://rmachine.haotui.com/thread-55-1-1.html 偏高偏低提示 [IF( [RMDBDataSet1."abnormalIndicator" ...
- DBCC--CHECKDB--不可被替代的原因
CHECKSUM不能发现的两类问题 1. 发生在内存中的页错误,如内存损坏+第三方程序修改等 2. MS SQL Server潜在BUG导致的逻辑错误,该类错误可以使用重建索引或重建约束来修复 CHE ...
- .net加密web.config文件
这篇文章我将介绍如何利用ASP.NET来加密和解密Web.config中连接字符串,之前只写了第二种方式,现在将两种方式都写出来,供大家参考.不管使用哪种方式我们在程序中都不需要写任何代码来解密连接字 ...
- VS2017仅我的代码警告
每次调试都会出现"仅我的代码"警告,特别的烦人,取消方法如下: 1.点击工具,选择选项. 2.选择调试→常规,取消“启动时若没有用户代码则发出警告(仅限托管)”选项.
- openvswitch BFD 简介
为了保护关键应用,网络中会设计有一定的冗余备份链路,网络发生故障时就要求网络设备能够快速检测出故障并将流量切换至备份链路以加快网络收敛速度.目前有些链路(如POS)通过硬件检测机制来实现快速故障检测. ...
- Weekly Contest 131
1021. Remove Outermost Parentheses A valid parentheses string is either empty (""), " ...
- webstorm keymap
http://www.jetbrains.com/webstorm/documentation/WebStorm_ReferenceCard.pdf
- daemon_int
摘自 UNP #include "unp.h" #include <syslog.h> #define MAXFD 64 extern int daemon_proc; ...
- include与file_get_contents区别
参考:http://www.cnblogs.com/bgwan/archive/2013/03/13/2957215.html 一,先来说file_get_contents 这个函数就 ...
- Spring+Ehcache
这里记录一下Spring+Ehcache的结合使用 1.添加依赖 <dependency> <groupId>org.springframework</groupId&g ...