Implementation of RTTI (VC)--Reprint

Source: Internet
Author: User

RTTI (Run time Type info)

This magical thing is used to store information about classes that are used to identify class objects at run time. C + + only records the name of the class and the inheritance chain of the class. Makes it possible to compile binary code, and the object can know its name (ASCII) and its position in the inheritance chain.

C + + provides a keyword typeid, a data type TypeInfo, and a corresponding header file typeinfo.h

1 #include <iostream>
2 #include <typeinfo>
3 using namespace std;
4
5 class Base
6 {
7 public:
8 virtual void F () {}//It must need the virtual table
9};

One
derive:public Base
, {
+
15};


Derive2:public Base
{
21};
base*
(pbase)
(
) type_info& typeinfo = typeID (pbase);
cout << typeinfo.name () <<endl;
+
,
if (NULL! = dynamic_cast<derive*> (pbase))
{
cout<< "type:derive" << Endl
+
(NULL! = dynamic_cast<derive2*> (pbase))
{
cout<< "type:derive2" <<e Ndl
*
//assert (0)
+}
}
*p
+
-int main ()
{
-Base Base1 = new Derive ();
F (PBASE1);
on
base* pbase = new Derive2 ();
F (pbase);
Wuyi

Out put:

1 class Base *
2 type:derive
3 Class Base *
4 Type:derive2

The visible Dynamic is determined at run time and is safe. So

1. How does the RTTI information bind to objects? When was it bound?

2. Why does the dynam_cast have to require a virtual function between the types of conversions? Otherwise the compilation does not pass.

Here's a question to answer.

3.RTTI How to bind to an object

Google, find information. The following figure is from the "Inside C + + Model", where RTTI's info is related to the object:

Class Point
{
Public
Point (float xval);
Virtual ~point ();
float x () const;
static int Pointcount ();
Protected
Virtual ostream& print (ostream &os) const;
float _x;
static int _point_count;
};

Its in-memory model:

Obviously Rtti info exists in the first item of the virtual table. The second question can be answered, because Rtti relies on virtual tables, so the classes corresponding to dynamic_cast must have virtual functions.

The following is verified in the VC,

In VC, we know that the virtual pointer to the virtual table, the corresponding virtual table the first item is the first virtual function. If we consider the virtual function to constitute a virtual table, then we can assume that Rtti info will go directly above the virtual table.

Verify below:

1. View the class name in Rtti in VC

From the chart above, the contents of the RTTI are empty. So the implementation of VC and the model in the book is inconsistent? Isn't rtti on the top of a virtual table? The following validation is followed:

2. Put the virtual table above the address of Rtti info, set to 0, then typeid can work? Can dynamic_cast still work? If you can also work, the data that this address points to is irrelevant.

If the Rtti pointer on the virtual table is empty, dynamic_cast cannot run, throwing an exception "std:: __non_rtti_object". That means the address, or the rtti. Where's the problem?

Try searching in Google, but it doesn't. So dynamic_cast relies on rtti information, then dynamic_cast's implementation begins to look. Take a look at his assembly code. So there is the following experiment.

3. How RTTI is implemented in VC.

Export the above code in assembly form to view.

24:derive * pderive = dynamic_cast<derive*> (pbase);
Push 0
Push OFFSET [Email protected]@@8
Push OFFSET [Email protected]@@8
Push 0
mov eax, DWORD PTR _PBASE$[EBP]
Push EAX
Call ___rtdynamiccast
Add ESP, 20; 00000014H
mov DWORD PTR _pderive$[ebp], eax

The realization of dynamic_cast depends on the object itself, as well as [email protected]@@8 and [email protected]@@8. Then continue to view the code

1; Listing generated by Microsoft (R) optimizing Compiler Version 14.00.50727.762
2
3 TITLE c:\Documents and Settings\zhangroc\desktop\tw\test\static_cast\static_cast.cpp
4.686P
5. XMM
6 include Listing.inc
7. Model Flat
8
9 Includelib MSVCRTD
Ten Includelib Oldnames
11
public [email protected][email protected]@[email protected]; ' String '
_data SEGMENT
__bad_alloc_message DD flat:[email protected][email protected]@[email protected]
_data ENDS
16; comdat [email protected][email protected]@[email protected]
-CONST SEGMENT
[Email protected][email protected]@[email protected] DB ' bad allocation ', 00H; ' String '
CONST ENDS
public [email protected]@@8; Base ' RTTI Type descriptor '
public [email protected]@@8; Derive ' RTTI Type descriptor '
public [email protected]@[email protected]; Derive::D erive
_main Public
EXTRN ___rtdynamiccast:proc
extrn [email Protected]@z:proc; operator NEW
EXTRN __rtc_checkesp:proc
EXTRN __rtc_shutdown:proc
EXTRN __rtc_initbase:proc
extrn [email Protected]@[email protected]:qword; Type_info:: ' vftable '
30; comdat [Email protected]@@8
31; File C:\Documents and Settings\zhangroc\desktop\tw\test\static_cast\static_cast.cpp
_data SEGMENT
[Email protected]@@8 DD flat:[email protected]@[email protected]; Base ' RTTI Type descriptor '
00H DD
DB ' [email protected]@ ', 00H
_data ENDS
37; comdat [Email protected]@@8
_data SEGMENT
[Email protected]@@8 DD flat:[email protected]@[email protected]; Derive ' RTTI Type descriptor '
DD 00H
DB ' [email protected]@ ', 00H
_data ENDS
43; Comdat RTC$TMZ
RTC$TMZ SEGMENT
__RTC_SHUTDOWN.RTC$TMZ DD Flat:__rtc_shutdown
RTC$TMZ ENDS
47; Comdat Rtc$imz
Rtc$imz SEGMENT
__rtc_initbase.rtc$imz DD Flat:__rtc_initbase
50; Function Compile Flags:/odtp/rtcsu/zi
Wuyi Rtc$imz ENDS
52; Comdat _main
_text SEGMENT
tv69 =-256; Size = 4
$T 3121 = 248; Size = 4
_pderive$ =-44; Size = 4
_rtti$ =-32; Size = 4
_ptable$ =-20; Size = 4
_pbase$ =-8; Size = 4
_main PROC; Comdat
61
62; 19: {
63
+ Push EBP
* * mov ebp, esp
256 Sub ESP,; 00000100H
EBX push
----the ESI
Push EDI
A. Lea EDI, DWORD PTR [ebp-256]
ECX mov, 64; 00000040H
EAX mov,-858993460; Cccccccch
Stosd Rep
74
75; 20:base *pbase = new Derive ();
76
4 push
[Email protected]@z; operator NEW
Add ESP, 4
* mov DWORD PTR $T 3121[EBP], eax
Bayi cmp DWORD PTR $T 3121[EBP], 0
Je Short [email protected]
ECX mov, DWORD PTR $T 3121[EBP]
[Email Protected]@[email protected]
$ mov DWORD PTR TV69[EBP], eax
About JMP short [email protected]
[Email protected]:
A. mov DWORD PTR TV69[EBP], 0
[Email protected]:
EAX mov, DWORD PTR TV69[EBP]
_PBASE$[EBP mov DWORD PTR [], eax
92
93; 21:int *ptable = (int*) (* (int*) pbase);
94
EAX mov, DWORD PTR _PBASE$[EBP]
ECX mov, DWORD PTR [EAX]
_PTABLE$[EBP mov DWORD PTR], ecx
98
99; 22:int *rtti = ptable-1;
100
101 mov eax, DWORD PTR _PTABLE$[EBP]
102 Sub EAX, 4
103 mov DWORD PTR _RTTI$[EBP], eax
104
105; 23:
106; 24:derive * pderive = dynamic_cast<derive*> (pbase);
107
108 Push 0
109 push OFFSET [email protected]@@8
Push OFFSET [Email protected]@@8
111 Push 0
EAX mov, DWORD PTR _PBASE$[EBP]
113 push EAX
___rtdynamiccast Call
20, add ESP, 00000014H
* * * mov DWORD PTR _pderive$[ebp], eax
117
118; 25:
117 U 26:}
120
121 xor eax, eax
122 Pop EDI
123 pop ESI
124 Pop EBX
add ESP, 256; 00000100H
126 CMP EBP, ESP
127 Call __rtc_checkesp
$ mov ESP, EBP
129 Pop EBP
0 ret
131 _main ENDP
_text ENDS
133 Public [email protected]@[email protected]; Derive:: ' vftable '
134 Public [email protected]@[email protected]; Base::base
135 public [email protected]@[email protected]; Derive:: ' RTTI complete Object Locator '
136 public [email protected]@8; Derive:: ' RTTI Class Hierarchy descriptor '
137 public [email protected]@8; Derive:: ' RTTI Base Class Array '
138 public [email protected][email protected]@[email protected]@8; Derive:: ' RTTI Base Class descriptor at (0,-1,0,64) '
139 Public [email protected][email protected]@[email protected]@8; Base:: ' RTTI base Class descriptor at (0,-1,0,64) '
[Email protected]@8; Base:: ' RTTI Class Hierarchy descriptor '
141 public [email protected]@8; Base:: ' RTTI base Class Array '
142 Public [email protected]@ @UAEXXZ; Base::f
143; comdat [Email protected]@8
144 Rdata$r SEGMENT
145 [Email protected]@8 DD flat:[email protected][email protected]@[email protected]@8; Base:: ' RTTI base Class Array '
146 Rdata$r ENDS
147; comdat [Email protected]@8
148 Rdata$r SEGMENT
149 [email protected]@8 DD 00H; Base:: ' RTTI Class Hierarchy descriptor '
00H DD
151 DD 01H
DD Flat:[email Protected]@8
153 Rdata$r ENDS
154; comdat [email protected][email protected]@[email protected]@8
155 Rdata$r SEGMENT
156 [Email protected][email protected]@[email protected]@8 DD flat:[email protected]@@8; Base:: ' RTTI base Class descriptor at (0,-1,0,64) '
157 DD 00H
158 DD 00H
159 DD 0ffffffffH
00H DD
161 DD 040H
162 DD Flat:[email Protected]@8
163 Rdata$r ENDS
164; comdat [email protected][email protected]@[email protected]@8
165 Rdata$r SEGMENT
166 [Email protected][email protected]@[email protected]@8 DD flat:[email protected]@@8; Derive:: ' RTTI Base Class descriptor at (0,-1,0,64) '
167 DD 01H
168 DD 00H
169 DD 0ffffffffH
00H DD
171 DD 040H
172 DD Flat:[email Protected]@8
173 Rdata$r ENDS
174; comdat [Email protected]@8
175 Rdata$r SEGMENT
176 [Email protected]@8 DD flat:[email protected][email protected]@[email protected]@8; Derive:: ' RTTI Base Class Array '
177 DD flat:[email Protected][email protected]@[email protected]@8
178 Rdata$r ENDS
179; comdat [Email protected]@8
Rdata$r SEGMENT
181 [email protected]@8 DD 00H; Derive:: ' RTTI Class Hierarchy descriptor '
182 DD 00H
183 DD 02H
184 DD Flat:[email Protected]@8
185 Rdata$r ENDS
186; comdat [email protected]@[email protected]
187 Rdata$r SEGMENT
188 [email protected]@[email protected] DD 00H; Derive:: ' RTTI complete Object Locator '
189 DD 00H
00H DD
191 DD Flat:[email Protected]@@8
192 DD Flat:[email Protected]@8
193 Rdata$r ENDS
194; comdat [email protected]@[email protected]
195 CONST SEGMENT
196 [email Protected]@[email protected] DD flat:[email protected]@[email protected]; Derive:: ' vftable '
197 DD Flat:[email protected]@ @UAEXXZ
198; Function Compile Flags:/odtp/rtcsu/zi
199 CONST ENDS
200; comdat [email protected]@[email protected]
201 _text SEGMENT
202 _this$ =-8; Size = 4
203 [email Protected]@[email protected] PROC; Derive::D erive, Comdat
204; _this$ = ecx
205 Push EBP
206 mov ebp, esp
207 Sub ESP, 204; 000000ccH
208 Push EBX
209 push ESI
The Push EDI
211 Push ECX
212 Lea EDI, DWORD PTR [ebp-204]
213 mov ecx, 51; 00000033H
214 mov eax,-858993460; Cccccccch
215 Rep Stosd
216 pop ECX
217 mov DWORD PTR _THIS$[EBP], ecx
218 mov ecx, DWORD PTR _THIS$[EBP]
219 Call [email protected]@[email protected]
EAX mov, DWORD PTR _THIS$[EBP]
221 mov DWORD PTR [eax], OFFSET [email protected]@[email protected]
222 mov eax, DWORD PTR _THIS$[EBP]
223 Pop EDI
224 pop ESI
225 pop ebx
226 add ESP, 204; 000000ccH
227 CMP EBP, esp
228 Call __rtc_checkesp
229 mov ESP, EBP
The pop EBP
231 RET 0
232 [email Protected]@[email protected] ENDP; Derive::D erive
233; Function Compile Flags:/odtp/rtcsu/zi
234 _text ENDS
235; comdat [Email protected]@ @UAEXXZ
236 _text SEGMENT
237 _this$ =-8; Size = 4
238 [email protected]@ @UAEXXZ PROC; Base::f, Comdat
239; _this$ = ecx
240
241; 8:virtual void F () {}
242
243 Push EBP
244 mov ebp, esp
245 Sub ESP, 204; 000000ccH
246 Push EBX
247 Push ESI
248 Push EDI
249 Push ECX
+ Lea EDI, DWORD PTR [ebp-204]
251 mov ecx, 51; 00000033H
252 mov eax,-858993460; Cccccccch
253 Rep Stosd
254 pop ECX
255 mov DWORD PTR _THIS$[EBP], ecx
The Pop EDI
257 pop ESI
258 pop EBX
259 mov ESP, EBP
260 Pop EBP
261 RET 0
262 [email protected]@ @UAEXXZ ENDP; Base::f
263 _text ENDS
public [email protected]@[email protected]; Base:: ' vftable '
265 Public [email protected]@[email protected]; Base:: ' RTTI complete Object Locator '
266; comdat [email protected]@[email protected]
267 Rdata$r SEGMENT
268 [email protected]@[email protected] DD 00H; Base:: ' RTTI complete Object Locator '
269 DD 00H
00H DD
271 DD Flat:[email Protected]@@8
272 DD Flat:[email Protected]@8
273 Rdata$r ENDS
274; comdat [email protected]@[email protected]
275 CONST SEGMENT
276 [email protected]@[email protected] DD flat:[email protected]@[email protected]; Base:: ' vftable '
277 DD Flat:[email protected]@ @UAEXXZ
278; Function Compile Flags:/odtp/rtcsu/zi
279 CONST ENDS
280; comdat [email protected]@[email protected]
281 _text SEGMENT
282 _this$ =-8; Size = 4
283 [email protected]@[email protected] PROC; Base::base, Comdat
284; _this$ = ecx
285 Push EBP
286 mov ebp, esp
287 Sub ESP, 204; 000000ccH
288 Push EBX
289 push ESI
290 Push EDI
291 push ECX
292 Lea EDI, DWORD PTR [ebp-204]
293 mov ecx, 51; 00000033H
294 mov eax,-858993460; Cccccccch
295 Rep Stosd
296 pop ECX
297 mov DWORD PTR _this$[ebp], ecx
298 mov eax, DWORD PTR _THIS$[EBP]
299 mov DWORD PTR [eax], OFFSET [email protected]@[email protected]
* mov eax, DWORD PTR _THIS$[EBP]
301 Pop EDI
302 Pop ESI
303 pop EBX
304 mov ESP, EBP
305 Pop Ebp
306 RET 0
307 [email Protected]@[email protected] ENDP; Base::base
308 _text ENDS
309 END

The original virtual table above the point is a Derive:: ' RTTI complete Object Locator. Google search below the keyword, with the following article
Http://www.openrce.org/articles/full_view/23
and the diagram:

Mystery revealed: The original virtual table above the address is pointing to a structure Derive:: ' RTTI Complete object Locator, this structure points to the name of the class, and its object inheritance chain.

This answers the first question, how does RTTI info bind to an object? At the time of object creation, when the constructor is called, the virtual table and Rtti info are created, so that dynamic cast can access the RTTI to ensure security.

There is also a problem, that is rtti efficiency under, try if a class inherits multiple layers, and has more than one inheritance, then the lookup chain is quite a link to traverse a list.

Transferred from: http://www.cnblogs.com/zhyg6516/archive/2011/03/07/1971898.html

Implementation of RTTI (VC)--Reprint

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.