dynamic_cast, RTTI, 整理
主要是参考下图,了解内存布局,然后写个实例程序就差不多明白了,但是需要熟悉指针转换。
1) 只有多态类才有RTTI信息,dynamic_cast正是运用RTTI进行转换,属于运行时类型检查。
2) dynamic_cast判断两个指针是否能转换时,用RTTI可以知道当前实际对象,然后遍历自己所有的父类,看是否有与目标类型一致的,如果有就可以进行转换。
3) dynamic_cast是安全的,可以通过检查返回值或异常捕捉来判断是否转成功。其中检查返回值用于指针转换,异常捕捉用于引用转换。
4) 补充一点,与static_cast不同,即使两个类没有直接继承关系,但是只要在一个类层次结构中,就有可能指向同一个对象,也就可以进行dynamic_cast。以下图为例,C继承自A,B。A, B指针就可以进行dynamic_cast,并可能成功。
C * pc = new C;
A* pa = pc;
B* pb = pc;
pb = dynamic_cast<B*>(pa); // 可以成功进行转换,因为二者指向的都是C对象。

下面的例子主要是关于RTTI的,打印出一个对象和她所有父类的运行时信息,这里的运行时信息主要是类的名字。
#include "iostream"
#include "string"
#include <typeinfo>
using namespace std; class Zero
{
public:
virtual void f111() { }
}; class Base : public Zero
{
public:
virtual void f() { }
}; class Deri1234567890ve : public Base
{
}; typedef unsigned long DWORD; struct PMD
{
int mdisp; //member displacement
int pdisp; //vbtable displacement
int vdisp; //displacement inside vbtable
}; struct RTTIBaseClassDescriptor
{
struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class
DWORD numContainedBases; //number of nested classes following in the Base Class Array
struct PMD where; //pointer-to-member displacement info
DWORD attributes; //flags, usually 0
}; struct TypeDescriptor
{
DWORD ptrToVTable;
DWORD spare;
char name[ ];
}; struct RTTIClassHierarchyDescriptor
{
DWORD signature; //always zero?
DWORD attributes; //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
DWORD numBaseClasses; //number of classes in pBaseClassArray
struct RTTIBaseClassArray* pBaseClassArray;
}; struct RTTICompleteObjectLocator { DWORD signature; //always zero ? DWORD offset; //offset of this vtable in the complete class DWORD cdOffset; //constructor displacement offset struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class //int * ptr;
struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy }; int main()
{
/*Base *pderive = new Deri1234567890ve();
int **ptr = (int **)(&pderive);
int *ptable = (int *)(*(int *)(*ptr));
int * rtti = ptable -1; RTTICompleteObjectLocator * RIIT_locator = (RTTICompleteObjectLocator *)( *(int*)rtti);
cout<<RIIT_locator->pTypeDescriptor->name<<endl;*/ Base *pderive = new Deri1234567890ve();
int *ptable = (int*)*(int*)pderive;
int * rtti = ptable -; // 显示当前类的名字“。。Deri1234567890ve。。”
RTTICompleteObjectLocator * RIIT_locator = (RTTICompleteObjectLocator *)( *(int*)rtti);
cout<<RIIT_locator->pTypeDescriptor->name<<endl; // 显示自己和所有父类的名字
int * p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray);
int * p2 = (int*)*(p1+);
TypeDescriptor* pDesc = (TypeDescriptor*)(*p2);
cout<<"One of Base Classes: "<<pDesc->name<<endl; p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray);
p2 = (int*)*(p1 + );
pDesc = (TypeDescriptor*)(*p2);
cout<<"One of Base Classes: "<<pDesc->name<<endl; p1 = (int*)(RIIT_locator->pClassDescriptor->pBaseClassArray);
p2 = (int*)*(p1);
pDesc = (TypeDescriptor*)(*p2);
cout<<"One of Base Classes: "<<pDesc->name<<endl;
}
参考:
浅议 Dynamic_cast 和 RTTI http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html
http://www.openrce.org/articles/full_view/23
asdfasdf
dynamic_cast, RTTI, 整理的更多相关文章
- RTTI: dynamic_cast typeid
dynamic_cast:将基类类型的指针向派生类指针安全转换.多用于下行转换.上行转换时,和static_cast是一样的.C++类型转换看这里.而const_cast用来修改类型的const或vo ...
- C++ 中dynamic_cast<>的使用方法小结 -判断类型-rtti
将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理 即会作一定的判断. 对指针进行dynamic ...
- 从零开始学C++之RTTI、dynamic_cast、typeid、类与类之间的关系uml
一.RTTI Run-time type information (RTTI) is a mechanism that allows the type of an object to be deter ...
- RTTI(运行时类型识别),typeid,dynamic_cast
dynamic_cast注意: 1.只能应用于指针和引用的转换: 2.要转换的类型中必须包含虚函数: 3.转换成功则返回地址,如果失败则返回NULL: 参见项目:RTTI
- RTTI、dynamic_cast、typeid、类与类之间的关系uml
一.RTTI Run-time type information (RTTI) is a mechanism that allows the type of an object to be deter ...
- RTTI之dynamic_cast运算符
#include <iostream> #include <cstdlib> #include <ctime> using std::cout; class Gra ...
- C 语言Struct 实现运行类型识别 RTTI
通过RTTI,能够通过基类的指针或引用来检索其所指对象的实际类型.c++通过下面两个操作符提供RTTI. (1)typeid:返回指针或引用所指对象的实际类型. (2)dynamic_cast: ...
- RTTI
RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. 编辑本段RTTI介绍 RTTI提 ...
- RTTI 运行时类型识别 及异常处理
RTTI 运行时类型识别 typeid ------ dynamic_cast dynamic_cast 注意事项: 1.只能应用于指针和引用之间的转化 2.要转换的类型中必须包含虚函数 3. ...
随机推荐
- Java this关键字详解
this 关键字用来表示当前对象本身,或当前类的一个实例,通过 this 可以调用本对象的所有方法和属性.例如: public class Demo{ public int x = 10; publi ...
- Word中如何让两个图片垂直居中对齐
如图,两个图片都剧终了,大小也一致,但是发现没有对齐,那是因为需要设置(矩阵框住的)缩进,让两个在一起,上下对齐.
- tiny4412 串口驱动分析六 --- TTY驱动架构
转载: http://www.linuxidc.com/Linux/2013-11/92639.htm 参考: http://blog.csdn.net/lamdoc/article/details/ ...
- 一个小时内学习SQLite数据库
一个小时内学习SQLite数据库 2012-05-11 10:24 红薯 OSCHINA 字号:T | T SQLite 是一个开源的嵌入式关系数据库,实现自包容.零配置.支持事务的SQL数据库引擎. ...
- BeagleBone Black板第四课:简单LED控制实验
BBB板第四课:简单LED控制实验 学习BBB板的终于目的是想像单片机一样做控制,但控制思路全然不一样(Linux下控制硬件设备实质就是对相关设备虚拟文件的读写).研究了几天头都大了还是没有进展,网上 ...
- ES怎么进行字段添加索引,并保留原有数据
1.先将原索引进行备份 curl -XPOST '192.168.46.163:9200/_reindex?pretty' -H 'Content-Type: application/json' -d ...
- 搭建elsticsearch集群 报错with the same id but is a different node instance解决办法
搭建elsticsearch集群 报错with the same id but is a different node instance解决办法 学习了:https://blog.csdn.net/q ...
- 11. 配置ContextPath【从零开始学Spring Boot】
转载:http://blog.csdn.net/linxingliang/article/details/51637036 spring boot默认是/ ,这样直接通过http://ip:port/ ...
- 《深入理解Android 卷III》第七章 深入理解SystemUI
<深入理解Android 卷III>即将公布,作者是张大伟.此书填补了深入理解Android Framework卷中的一个主要空白,即Android Framework中和UI相关的部分. ...
- MySql中文乱码问题(3)
MySql的client是在dos界面上,然而dos界面默认的字符集编码方式是:GBK (1).MySql字符转换原理图 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi ...