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
8struct 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
41class CObject
42{
43public:
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
65class 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};
76CRuntimeClass* A::GetRuntimeClass() const
77{ return ((CRuntimeClass*)(&A::classA)); }
78
79void 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}
2#define LPCSTR char *
3#define BOOL bool
4#define TRUE true
5#define FALSE false
6#define NULL 0
7
8struct 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
41class CObject
42{
43public:
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
65class 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};
76CRuntimeClass* A::GetRuntimeClass() const
77{ return ((CRuntimeClass*)(&A::classA)); }
78
79void 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}