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. ...
随机推荐
- Windows下将ISO镜像制作成U盘启动的工具(U盘启动工具/UltraISO/Rufus/Universal-USB)
说明:基于Windows的U盘启动制作都是非常的简单,在软件上指定ISO文件之后,一般都是选择写入到哪个U盘即可. 1.UltraISO 2.Rufus 3.Universal-USB 4.大白菜
- tiny4412 串口驱动分析一 --- u-boot中的串口驱动
作者:彭东林 邮箱:pengdonglin137@163.com 开发板:tiny4412ADK+S700 4GB Flash 主机:Wind7 64位 虚拟机:Vmware+Ubuntu12_04 ...
- 在Android App中集成Google登录
技术文章 来源:码农网 发布:2016-09-19 浏览:194 摘要:今天,几乎所有的web和移动app都自带谷歌和Facebook登录,这对app开发者和用户来说是一个非常有用的功能,因为几乎每个 ...
- andriod读写XML
AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?> <manifest xm ...
- Linux查看目录大小
du -ah --max-depth=1 a表示显示目录下所有的文件和文件夹(不含子目录) h表示以人类能看懂的方式 max-depth表示目录的深度
- sass高级语法的补充
1. 继承 2.混入 3.函数 我这篇博客需要点基础才能看懂, 但我这篇博客是对上一篇的 sass高级语法 的补充 从这方面来看也无所谓了
- KodExplorer介绍
KodExplorer介绍 KOD·简介 官方网站https://kodcloud.com/ KodExplorer可道云,原名芒果云,是一款基于 PHP 开发的开源 WEB 网页版轻量级私有云和在线 ...
- Loadrunner 工作原理图
1.LoadRunner的总体架构图,从图中可以看出组件VUGen, Controller和Analysis之间的关系. 2.LoadRunner的工作原理,从图中可以看出如何利用LoadRunner ...
- 《Microsoft Sql server 2008 Internals》读书笔记--第六章Indexes:Internals and Management(1)
<Microsoft Sql server 2008 Internals>索引文件夹: <Microsoft Sql server 2008 Internals>读书笔记--文 ...
- 【Excle数据透视表】如何让字段标题不显示“求和项”
我们做好了数据透视表之后是下面这个样子的 这个样子一点都不好看,那么如何去掉"求和项"呢? 步骤 方法① 单击B3单元格→编辑区域输入"数量 "→Enter(也 ...