Mfc rtti.
先放上分析后,并且简化后的源代码,有时间在说 1
#include <stdio.h>
2
#define LPCSTR char *
3
#define BOOL bool
4
#define TRUE true
5
#define FALSE false
6
#define NULL 0
7
8
struct CRuntimeClass
9
{
10
// Attributes
11
LPCSTR m_lpszClassName;
12
int m_nObjectSize;
13
14
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const
15
{
16
// simple SI case
17
const CRuntimeClass* pClassThis = this;
18
while (pClassThis != NULL)
19
{
20
if (pClassThis == pBaseClass)
21
return TRUE;
22
pClassThis = pClassThis->m_pBaseClass;
23
}
24
return FALSE; // walked to the top, no match
25
}
26
27
void PrintAll()
28
{
29
for(CRuntimeClass * pc=this; pc; pc=pc->m_pBaseClass)
30
{
31
printf("->%s", pc->m_lpszClassName);
32
}
33
printf("\n");
34
}
35
CRuntimeClass* m_pBaseClass; // linked list of registered classes
36
};
37
38
39
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))
40
41
class CObject
42
{
43
public:
44
static CRuntimeClass classCObject;
45
46
virtual CRuntimeClass * GetRuntimeClass() const //must be virtual
47
{
48
return &CObject::classCObject;
49
}
50
51
BOOL IsKindOf(const CRuntimeClass* pClass) const
52
{
53
CRuntimeClass* pClassThis = GetRuntimeClass();
54
55
return pClassThis->IsDerivedFrom(pClass);
56
}
57
58
};
59
60
__declspec(selectany) CRuntimeClass CObject::classCObject =
61
{
62
"CObject", sizeof(class CObject), NULL
63
};
64
65
class A:public CObject
66
{
67
public:
68
static const CRuntimeClass classA;
69
virtual CRuntimeClass* GetRuntimeClass() const;
70
};
71
72
__declspec(selectany) const CRuntimeClass A::classA =
73
{
74
"A", sizeof(class A), &CObject::classCObject
75
};
76
CRuntimeClass* A::GetRuntimeClass() const
77
{ return ((CRuntimeClass*)(&A::classA)); }
78
79
void main()
80
{
81
A a;
82
printf("%d\n", a.IsKindOf(RUNTIME_CLASS(CObject)));
83
printf("%d\n", a.IsKindOf(RUNTIME_CLASS(A)));
84
//printf("%d\n", a.IsKindOf(RUNTIME_CLASS(int))); //Compile Fail
85
86
RUNTIME_CLASS(CObject)->PrintAll();
87
RUNTIME_CLASS(A)->PrintAll();
88
}
#include <stdio.h>2
#define LPCSTR char *3
#define BOOL bool4
#define TRUE true5
#define FALSE false6
#define NULL 07

8
struct CRuntimeClass9
{10
// Attributes11
LPCSTR m_lpszClassName;12
int m_nObjectSize;13
14
BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const15
{16
// simple SI case17
const CRuntimeClass* pClassThis = this;18
while (pClassThis != NULL)19
{20
if (pClassThis == pBaseClass)21
return TRUE;22
pClassThis = pClassThis->m_pBaseClass;23
}24
return FALSE; // walked to the top, no match25
}26
27
void PrintAll()28
{29
for(CRuntimeClass * pc=this; pc; pc=pc->m_pBaseClass)30
{31
printf("->%s", pc->m_lpszClassName);32
}33
printf("\n");34
}35
CRuntimeClass* m_pBaseClass; // linked list of registered classes36
};37

38

39
#define RUNTIME_CLASS(class_name) ((CRuntimeClass*)(&class_name::class##class_name))40

41
class CObject42
{43
public:44
static CRuntimeClass classCObject; 45
46
virtual CRuntimeClass * GetRuntimeClass() const //must be virtual47
{48
return &CObject::classCObject;49
}50
51
BOOL IsKindOf(const CRuntimeClass* pClass) const52
{53
CRuntimeClass* pClassThis = GetRuntimeClass();54

55
return pClassThis->IsDerivedFrom(pClass);56
}57
58
};59

60
__declspec(selectany) CRuntimeClass CObject::classCObject = 61
{ 62
"CObject", sizeof(class CObject), NULL 63
}; 64

65
class A:public CObject66
{67
public: 68
static const CRuntimeClass classA; 69
virtual CRuntimeClass* GetRuntimeClass() const; 70
};71

72
__declspec(selectany) const CRuntimeClass A::classA = 73
{ 74
"A", sizeof(class A), &CObject::classCObject 75
}; 76
CRuntimeClass* A::GetRuntimeClass() const 77
{ return ((CRuntimeClass*)(&A::classA)); } 78

79
void main()80
{81
A a;82
printf("%d\n", a.IsKindOf(RUNTIME_CLASS(CObject)));83
printf("%d\n", a.IsKindOf(RUNTIME_CLASS(A)));84
//printf("%d\n", a.IsKindOf(RUNTIME_CLASS(int))); //Compile Fail85
86
RUNTIME_CLASS(CObject)->PrintAll();87
RUNTIME_CLASS(A)->PrintAll();88
}- 上一篇 一道题目.
- 下一篇 关于default constructor一个要注意的地方.

