所谓的反射当然不是自动化的,而是需要自己打标记的。下面会展示两份文件,告诉大家我这个做了一半的反射是怎么工作的。写这个东西的主要目的是,将来可以实现序列化,譬如说序列化到流,或者序列化到XML文件,或者做其他的事情等等(譬如说使用类名创建对象并进行修改)。
首先是运行结果。下面的结果是console application窗口上打印的。因为太长所以没截图。我创建了三个对象,然后使用反射将他们的内容打印了出来:
1 Cat {
2 BodyLength = 50
3 TailLength = 30
4 FingerCount = 18
5 Age = 10
6 Weight = 100
7 }
8 Fish {
9 MaxDepth = 3000.0
10 Length = 25
11 Age = 20
12 Weight = 200
13 }
14 Bird {
15 CanFly = true
16 Name = Jack
17 Age = 30
18 Weight = 300
19 }
20 Human {
21 Name = 囧Smith
22 MainPat = Cat {
23 BodyLength = 40
24 TailLength = 20
25 FingerCount = 18
26 Age = 5
27 Weight = 150
28 }
29 MainTransportation = Bird {
30 CanFly = true
31 Name = Red Dragon
32 Age = 3000
33 Weight = 300
34 }
35 OtherPats = VL_AutoPtr<Animal>[4] {
36 item[0] = Cat {
37 BodyLength = 50
38 TailLength = 30
39 FingerCount = 18
40 Age = 10
41 Weight = 100
42 }
43 item[1] = Fish {
44 MaxDepth = 3000.0
45 Length = 25
46 Age = 20
47 Weight = 200
48 }
49 item[2] = Bird {
50 CanFly = true
51 Name = Jack
52 Age = 30
53 Weight = 300
54 }
55 item[3] = <NULL>
56 }
57 OtherTranspotations = Bird[3] {
58 item[0] = Bird {
59 CanFly = true
60 Name = Blue Dragon 1
61 Age = 3000
62 Weight = 300
63 }
64 item[1] = Bird {
65 CanFly = true
66 Name = Blue Dragon 2
67 Age = 3100
68 Weight = 300
69 }
70 item[2] = Bird {
71 CanFly = true
72 Name = Blue Dragon 3
73 Age = 3200
74 Weight = 300
75 }
76 }
77 OtherPatsList = VL_List<VL_AutoPtr<Animal> , false> {
78 item[0] = Cat {
79 BodyLength = 50
80 TailLength = 30
81 FingerCount = 18
82 Age = 10
83 Weight = 100
84 }
85 item[1] = Fish {
86 MaxDepth = 3000.0
87 Length = 25
88 Age = 20
89 Weight = 200
90 }
91 item[2] = Bird {
92 CanFly = true
93 Name = Jack
94 Age = 30
95 Weight = 300
96 }
97 }
98 OtherTranspotationsList = VL_List<Bird , false> {
99 item[0] = Bird {
100 CanFly = true
101 Name = Green Dragon 1
102 Age = 3000
103 Weight = 300
104 }
105 item[1] = Bird {
106 CanFly = true
107 Name = Green Dragon 2
108 Age = 3010
109 Weight = 300
110 }
111 item[2] = Bird {
112 CanFly = true
113 Name = Green Dragon 3
114 Age = 3020
115 Weight = 300
116 }
117 }
118 FingerCount = 20
119 Age = 16
120 Weight = 2000
121 }
122
下面是main函数的代码。这里声明了几个类,然后标记了一下感兴趣的成员:
1 #include "..\..\..\..\VL++\Library\Platform\VL_Console.h"
2 #include "..\..\..\..\VL++\Library\Data\Inspector\VL_ObjectInspector.h"
3 #include "..\..\..\..\VL++\Library\Data\Inspector\VL_ObjectStrconv.h"
4
5 using namespace vl;
6 using namespace vl::platform;
7 using namespace vl::inspector;
8
9 class Animal : public VL_Base
10 {
11 public:
12 VInt Age;
13 VInt Weight;
14 };
15
16 class Mammalian : public Animal
17 {
18 public:
19 VInt FingerCount;
20 };
21
22 class Cat : public Mammalian
23 {
24 public:
25 VInt BodyLength;
26 VInt TailLength;
27
28 Cat()
29 {
30 Age=10;
31 Weight=100;
32 FingerCount=18;
33 BodyLength=50;
34 TailLength=30;
35 }
36 };
37
38 class Fish : public Animal
39 {
40 public:
41 VDouble MaxDepth;
42 VInt Length;
43
44 Fish()
45 {
46 Age=20;
47 Weight=200;
48 MaxDepth=3000;
49 Length=25;
50 }
51 };
52
53 class Bird : public Animal
54 {
55 public:
56 VBool CanFly;
57 VUnicodeString Name;
58
59 Bird()
60 {
61 Age=30;
62 Weight=300;
63 CanFly=true;
64 Name=L"Jack";
65 }
66 };
67
68 class Human : public Mammalian
69 {
70 public:
71 VUnicodeString Name;
72 VL_AutoPtr<Animal> MainPat;
73 Bird MainTransportation;
74 VL_AutoPtr<Animal> OtherPats[4];
75 Bird OtherTranspotations[3];
76 VL_List<VL_AutoPtr<Animal> , false , Animal*> OtherPatsList;
77 VL_List<Bird , false> OtherTranspotationsList;
78
79 Human()
80 {
81 Age=16;
82 Weight=2000;
83 FingerCount=20;
84 Name=L"囧Smith";
85
86 Cat* cat=new Cat;
87 cat->Age=5;
88 cat->Weight=150;
89 cat->BodyLength=40;
90 cat->TailLength=20;
91 MainPat=cat;
92
93 MainTransportation.Name=L"Red Dragon";
94 MainTransportation.Age=3000;
95
96 OtherPats[0]=new Cat;
97 OtherPats[1]=new Fish;
98 OtherPats[2]=new Bird;
99
100 for(VInt i=0;i<3;i++)
101 {
102 OtherTranspotations[i].Name=L"Blue Dragon "+VUnicodeString(i+1);
103 OtherTranspotations[i].Age=3000+i*100;
104 }
105
106 OtherPatsList.Add(new Cat);
107 OtherPatsList.Add(new Fish);
108 OtherPatsList.Add(new Bird);
109
110 for(VInt i=0;i<3;i++)
111 {
112 OtherTranspotationsList.Add(Bird());
113 OtherTranspotationsList[i].Name=L"Green Dragon "+VUnicodeString(i+1);
114 OtherTranspotationsList[i].Age=3000+i*10;
115 }
116 }
117 };
118
119 VL_BEGIN_INSPECTOR_DECLARATION
120
121 VL_BEGIN_BASE_CLASS(Animal)
122 VL_ADD_CLASS_MEMBER(Animal,Age)
123 VL_ADD_CLASS_MEMBER(Animal,Weight)
124 VL_END_CLASS(Animal)
125
126 VL_BEGIN_SUB_CLASS(Mammalian,Animal)
127 VL_ADD_CLASS_MEMBER(Mammalian,FingerCount)
128 VL_END_CLASS(Mammalian)
129
130 VL_BEGIN_SUB_CLASS(Cat,Mammalian)
131 VL_ADD_CLASS_MEMBER(Cat,BodyLength)
132 VL_ADD_CLASS_MEMBER(Cat,TailLength)
133 VL_END_CLASS(Cat)
134
135 VL_BEGIN_SUB_CLASS(Fish,Animal)
136 VL_ADD_CLASS_MEMBER(Fish,MaxDepth)
137 VL_ADD_CLASS_MEMBER(Fish,Length)
138 VL_END_CLASS(Fish)
139
140 VL_BEGIN_SUB_CLASS(Bird,Animal)
141 VL_ADD_CLASS_MEMBER(Bird,CanFly)
142 VL_ADD_CLASS_MEMBER(Bird,Name)
143 VL_END_CLASS(Bird)
144
145 VL_BEGIN_SUB_CLASS(Human,Mammalian)
146 VL_ADD_CLASS_MEMBER(Human,Name)
147 VL_ADD_CLASS_MEMBER(Human,MainPat)
148 VL_ADD_CLASS_MEMBER(Human,MainTransportation)
149 VL_ADD_CLASS_MEMBER(Human,OtherPats)
150 VL_ADD_CLASS_MEMBER(Human,OtherTranspotations)
151 VL_ADD_CLASS_MEMBER(Human,OtherPatsList)
152 VL_ADD_CLASS_MEMBER(Human,OtherTranspotationsList)
153 VL_END_CLASS(Human)
154
155 VL_BEGIN_INSPECTOR_MANAGER(AnimalManager)
156 VL_BIND_INSPECTOR(Animal)
157 VL_BIND_INSPECTOR(Mammalian)
158 VL_BIND_INSPECTOR(Cat)
159 VL_BIND_INSPECTOR(Fish)
160 VL_BIND_INSPECTOR(Bird)
161 VL_BIND_INSPECTOR(Human)
162 VL_END_INSPECTOR_MANAGER
163
164 VL_END_INSPECTOR_DECLARATION
165
166 void PrintAnimal(VL_InspectorManager::Ptr Manager , Animal* aAnimal)
167 {
168 VL_InspectorConverterManager Converter;
169 Converter.AddNormalConverter(new VL_InspectorReader);
170
171 VL_ObjectInspector::Ptr Inspector=Manager->GetInspector(VL_InspectorSelector<Animal>::GetID());
172 GetConsole()->WriteLine(Converter.FindToStringConverter(Inspector)->ConvertToString(Inspector,aAnimal));
173 }
174
175 void vlmain()
176 {
177 GetConsole()->SetTitle(L"Vczh Library++ 2.0 Type Information Test");
178 GetConsole()->SetTestMemoryLeaks(true);
179 GetConsole()->SetPauseOnExit(true);
180
181 VL_InspectorManager::Ptr Manager=VL_GET_INSPECTOR_MANAGER(AnimalManager);
182
183 Cat cat;
184 Fish fish;
185 Bird bird;
186 Human human;
187 PrintAnimal(Manager,&cat);
188 PrintAnimal(Manager,&fish);
189 PrintAnimal(Manager,&bird);
190 PrintAnimal(Manager,&human);
191 }
最后是一个ConvertToString的函数,来展示如何读取数据的:
1 VUnicodeString VL_InspectorReader::ConvertToString(VL_ObjectInspector::Ptr Inspector , VPointer Data , VUnicodeString Prefix)
2 {
3 if(Data==0)
4 {
5 return L"<NULL>";
6 }
7 else if(VL_AutoPtr<VL_StructInspector> Struct=Inspector)
8 {
9 Struct=Struct->GetRealObject(Data);
10 VUnicodeString String=Struct->GetID()+L" {\r\n";
11 while(Struct)
12 {
13 for(VInt i=0;i<Struct->GetMemberCount();i++)
14 {
15 VL_MemberInspector::Ptr Member=Struct->GetMember(i);
16 String+=Prefix+L" "+Member->GetMemberName()+L" = ";
17 String+=ConvertToString(Member->GetMemberInspector(),Member->GetMember(Data),Prefix+L" ")+L"\r\n";
18 }
19 Data=Struct->GetBase(Data);
20 Struct=Struct->GetBaseInspector();
21 }
22 String+=Prefix+L"}";
23 return String;
24 }
25 else if(VL_AutoPtr<VL_CollectionInspector> Collection=Inspector)
26 {
27 VUnicodeString String=Collection->GetID()+L" {\r\n";
28 for(VInt i=0;i<Collection->GetMemberCount(Data);i++)
29 {
30 VL_MemberInspector::Ptr Member=Collection->GetMember(i,Data);
31 String+=Prefix+L" item["+VUnicodeString(i)+L"] = ";
32 String+=ConvertToString(Member->GetMemberInspector(),Member->GetMember(Data),Prefix+L" ")+L"\r\n";
33 }
34 String+=Prefix+L"}";
35 return String;
36 }
37 else
38 {
39 VL_InspectorConverter::Ptr Converter=FManager->FindToStringConverter(Inspector);
40 if(Converter)
41 {
42 return Converter->ConvertToString(Inspector,Data);
43 }
44 else
45 {
46 return L"<UNKNOWN>";
47 }
48 }
49 }
posted on 2009-06-25 06:48
陈梓瀚(vczh) 阅读(3559)
评论(4) 编辑 收藏 引用 所属分类:
C++