对象与对象的类型信息----获取对象的RTTI信息
来源:互联网 发布:淘宝资源怎么找 编辑:程序博客网 时间:2024/06/12 01:05
对象与对象的类型信息----获取对象的RTTI信息
梦在天涯 在上篇文章里问可不可以研究下对象与对象的类型信息怎么联系起来的,就是当调用dynamic_cast的时候为什么能够正确的识别对象的类型
RTTI(Run Time Type Identification)运行时类型识别是有编译器在编译器生成的特殊类型信息,包括对象继承关系,对象本身的描述,RTTI是为多态而生成的信息,所以只有具有虚函数的对象在会生成
那RTTI在哪里呢?
MSVC编译器在vftable前设置了一个指针,指向叫做“Complete Object Locator”(完整对象定位器)的结构。这样称呼是因为它允许编译器从特定的vftable指针(因为一个类可能有若干vftable)找到完整对象的位置。COL就像如下定义:
请看如下代码:
1#include "iostream"
2#include "string"
3
4
5using namespace std;
6class Aclass
7{
8public:
9 int a;
10 virtual void setA(int tmp)
11 {
12 a=tmp;
13 cout<<a<<endl;
14 }
15};
16class Bclass:public Aclass
17{
18public:
19 virtual void setA(int tmp)
20 {
21 a=tmp+10;
22 cout<<a<<endl;
23 }
24public:
25 void print()
26 {
27 cout<<a<<endl;
28 }
29};
30class Cclass:public Bclass
31{
32};
33typedef unsigned long DWORD;
34struct TypeDescriptor
35{
36 DWORD ptrToVTable;
37 DWORD spare;
38 char name[8];
39};
40struct PMD
41{
42
43 int mdisp; //member displacement
44
45 int pdisp; //vbtable displacement
46
47 int vdisp; //displacement inside vbtable
48
49};
50struct RTTIBaseClassDescriptor
51
52{
53
54 struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class
55
56 DWORD numContainedBases; //number of nested classes following in the Base Class Array
57
58 struct PMD where; //pointer-to-member displacement info
59
60 DWORD attributes; //flags, usually 0
61
62};
63
64struct RTTIClassHierarchyDescriptor
65{
66
67 DWORD signature; //always zero?
68
69 DWORD attributes; //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
70
71 DWORD numBaseClasses; //number of classes in pBaseClassArray
72
73 struct RTTIBaseClassArray* pBaseClassArray;
74
75};
76
77struct RTTICompleteObjectLocator
78
79{
80
81 DWORD signature; //always zero ?
82
83 DWORD offset; //offset of this vtable in the complete class
84
85 DWORD cdOffset; //constructor displacement offset
86
87 struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class
88
89 struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy
90
91
92};
93
94
95int _tmain(int argc, _TCHAR* argv[])
96{
97 Aclass* ptra=new Bclass;
98 int ** ptrvf=(int**)(ptra);
99 RTTICompleteObjectLocator str=
100 *((RTTICompleteObjectLocator*)(*((int*)ptrvf[0]-1)));
101 //abstract class name from RTTI
102 string classname(str.pTypeDescriptor->name);
103 classname=classname.substr(4,classname.find("@@")-4);
104 cout<<classname<<endl;
105 system("pause");
106 return 0;
107}
108
2#include "string"
3
4
5using namespace std;
6class Aclass
7{
8public:
9 int a;
10 virtual void setA(int tmp)
11 {
12 a=tmp;
13 cout<<a<<endl;
14 }
15};
16class Bclass:public Aclass
17{
18public:
19 virtual void setA(int tmp)
20 {
21 a=tmp+10;
22 cout<<a<<endl;
23 }
24public:
25 void print()
26 {
27 cout<<a<<endl;
28 }
29};
30class Cclass:public Bclass
31{
32};
33typedef unsigned long DWORD;
34struct TypeDescriptor
35{
36 DWORD ptrToVTable;
37 DWORD spare;
38 char name[8];
39};
40struct PMD
41{
42
43 int mdisp; //member displacement
44
45 int pdisp; //vbtable displacement
46
47 int vdisp; //displacement inside vbtable
48
49};
50struct RTTIBaseClassDescriptor
51
52{
53
54 struct TypeDescriptor* pTypeDescriptor; //type descriptor of the class
55
56 DWORD numContainedBases; //number of nested classes following in the Base Class Array
57
58 struct PMD where; //pointer-to-member displacement info
59
60 DWORD attributes; //flags, usually 0
61
62};
63
64struct RTTIClassHierarchyDescriptor
65{
66
67 DWORD signature; //always zero?
68
69 DWORD attributes; //bit 0 set = multiple inheritance, bit 1 set = virtual inheritance
70
71 DWORD numBaseClasses; //number of classes in pBaseClassArray
72
73 struct RTTIBaseClassArray* pBaseClassArray;
74
75};
76
77struct RTTICompleteObjectLocator
78
79{
80
81 DWORD signature; //always zero ?
82
83 DWORD offset; //offset of this vtable in the complete class
84
85 DWORD cdOffset; //constructor displacement offset
86
87 struct TypeDescriptor* pTypeDescriptor; //TypeDescriptor of the complete class
88
89 struct RTTIClassHierarchyDescriptor* pClassDescriptor; //describes inheritance hierarchy
90
91
92};
93
94
95int _tmain(int argc, _TCHAR* argv[])
96{
97 Aclass* ptra=new Bclass;
98 int ** ptrvf=(int**)(ptra);
99 RTTICompleteObjectLocator str=
100 *((RTTICompleteObjectLocator*)(*((int*)ptrvf[0]-1)));
101 //abstract class name from RTTI
102 string classname(str.pTypeDescriptor->name);
103 classname=classname.substr(4,classname.find("@@")-4);
104 cout<<classname<<endl;
105 system("pause");
106 return 0;
107}
108
输出结果:
在RTTI运行时结构体中包含许多丰富的信息,甚至我们可以利用一个实例的RTTI信息去复原整个类继承图谱
而对于dynamic_cast也是利用这个信息来准确的识别实例所对应的类型,不过如果对于没有多态的实例,dynamic_cast所做的也只是和编译器类型转换一样的事情,仅仅是通过类型和继承关系进行转换,还是看例子吧:
1class mother
2{
3 int a;
4 int b;
5};
6class father
7{
8 double c;
9};
10class son:public mother,public father
11{
12 char a;
13 short c;
14};
15
16int _tmain(int argc, _TCHAR* argv[])
17{
18 mother* m=new son();
19 father* f=dynamic_cast<father*>(m);
20 system("pause");
21 return 0;
22}
运行会得到以下错误:2{
3 int a;
4 int b;
5};
6class father
7{
8 double c;
9};
10class son:public mother,public father
11{
12 char a;
13 short c;
14};
15
16int _tmain(int argc, _TCHAR* argv[])
17{
18 mother* m=new son();
19 father* f=dynamic_cast<father*>(m);
20 system("pause");
21 return 0;
22}
error C2683: “dynamic_cast”:“mother”不是多态类型
修改如下
class mother
{
int a;
int b;
virtual void fun()
{
}
};
一切正常
就说这么多吧,欢迎多交流
- 对象与对象的类型信息----获取对象的RTTI信息
- java 类型信息(RTTI) 中 Class对象的理解
- 【python】获取对象的类型和信息
- 获取对象类型信息+查看对象类型的结构+设置信息深度
- Java RTTI(类型信息)(.class 类对象)
- 获取关于 ResultSet 对象中列的类型和属性信息的对象
- 获取关于 ResultSet 对象中列的类型和属性信息的对象
- SQL Server数据库对象信息的获取
- 如何获取GDI对象的属性信息
- 使用request对象获取表单的信息
- JSP获取异常信息的exception对象
- python 获取对象信息的方法
- Python对象 继承 多态 获取对象信息 类的属性
- python获取对象信息
- 获取对象信息
- Python 获取对象信息
- 获取对象信息
- Python 获取对象信息
- virtualBox使用复制的VDI出现UUID重复的错误(解决方法)
- J2EE开发常用框架介绍
- 《Inter汇编语言程序设计》8.6 创建多模块程序(INVOKE PROTO)
- git 命令之git rebase 用法
- ACE 6.1.3 发布,面向对象的工具开发包
- 对象与对象的类型信息----获取对象的RTTI信息
- C#让任何一个控件都可以全屏播放
- .Net理论常识整理——第一日
- 2013年4月_武科大程序设计大赛(复赛)_解题报告(problem 1005)
- VC与Matlab接口编程之Matcom安装配置
- Android 动画效果animation
- 自动提款机
- C++使用hash_map时警告
- php分析tsv/csv文件