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. ...
随机推荐
- 使用TensorFlow实现神经网络的介绍
http://www.toutiao.com/i6414029277641048577/
- Word中如何公式居中标号右对齐
1.鼠标居中 2.插入一行三列表格 3.选中第一个表格,右键-表格属性-单元格-选项:然后回到单元格设置垂直居中,宽度为15%,同理第三个单元格,不过中间单元格也要设置,宽度为70%,这个word没有 ...
- 【java】java反射 Field类的研究使用
java反射 Field类的研究使用 user.getClass().getFields() 和 user.getClass().getDeclaredFields(); 的区别是什么?
- 单元测试方法属性(Unit Test Method Attribute)
Additional test attributes(可以在测试方法上使用的属性)As you have seen, the unit-testing subsystem within Visual ...
- [置顶]
kubernetes资源类型--deployment
Deployment(中文意思为部署.调度)提供了一种更加简单的更新RC和Pod的机制,K8S版本1.2实现的.通过在Deployment中描述所期望的集群状态,Deployment Controll ...
- NPM安装报错:WARN PACKAGE.JSON, NO REPOSITORY FIELDS
今天在安装npm包时遇到了这个错误,出现如下提示: npm WARN package.json xxx@0.0.0 No repository field. npm WARN package.json ...
- python的__call__、__str__、__repr__、__init__、__class__、__name___、__all__、__doc__、__del__等魔术方法的作用
python中,一切都是对象 在Python中,所有以“__”双下划线包起来的方法,都统称为“Magic Method”--魔术方法 1.__call__:作用是把类实例变成一个可调用对象 在Pyth ...
- Hive错误记录
创建表报错 Error: Error while processing statement: FAILED: Execution Error, return code 1 from org.apach ...
- xtrabackup详解
xtrabackup是Percona公司CTO Vadim参与开发的一款基于InnoDB的在线热备工具,具有开源,免费,支持在线热备,备份恢复速度快,占用磁盘空间小等特点,并且支持不同情况下的多种备份 ...
- R 包的安装,使用,更新
R包的使用方法 包就是提供了种类繁多的函数,当然还有它的一些数据集,可以使用这些函数来操作这些数据集,来学习使用. library(),当前的工作环境里,可以使用的包 包的帮助文档:help(pack ...