14.14 Run-Time Type Information (RTTI)


14.14 Run-Time Type Information (RTTI)

When working with an object variable (as opposed to a pointer to an object), the type of that object is obvious: It's the variable's declared type. Therefore, at both compile time and runtime the program trivially knows the type of the object. When working with pointers to objects you cannot, in the general case, determine the type of an object a pointer references. However, at runtime it is possible to determine the object's actual type. This section discusses how to detect the underlying object's type and how to use this information.

If you have a pointer to an object and that pointer's type is some base class, at runtime the pointer could point at an object of the base class or any derived type. At compile time it is not possible to determine the exact type of an object at any instant. To see why, consider the following short example:

      ReturnSomeObject();          // Returns a pointer to some class in ESI.      mov( esi, ptrToObject ); 

The routine ReturnSomeObject returns a pointer to an object in ESI. This could be the address of some base class object or a derived class object. At compile time there is no way for the program to know what type of object this function returns. For example, ReturnSomeObject could ask the user what value to return so the exact type could not be determined until the program actually runs and the user makes a selection.

In a perfectly designed program, there probably is no need to know a generic object's actual type. After all, the whole purpose of object-oriented programming and inheritance is to produce general programs that work with lots of different objects without having to make substantial changes to the program. In the real world, however, programs may not have a perfect design and sometimes it's nice to know the exact object type a pointer references. Runtime type information, or RTTI, gives you the capability of determining an object's type at runtime, even if you are referencing that object using a pointer to some base class of that object.

Perhaps the most fundamental RTTI operation you need is the ability to ask if a pointer contains the address of some specific object type. Many objectoriented languages (e.g., Delphi) provide an IS operator that provides this functionality. IS is a boolean operator that returns true if its left operand (a pointer) points at an object whose type matches the right operand (which must be a type identifier). The typical syntax is generally the following:

 ObjectPointerOrVar is ClassType 

This operator would return true if the variable is of the specified class; it returns false otherwise. Here is a typical use of this operator (in the Delphi language)

      if( ptrToNumeric is uint ) then begin           .           .           .      end; 

It's actually quite simple to implement this functionality in HLA. As you may recall, each class is given its own virtual method table. Whenever you create an object, you must initialize the pointer to the VMT with the address of that class's VMT. Therefore, the VMT pointer field of all objects of a given class type contains the same pointer value, and this pointer value is different from the VMT pointer field of all other classes. We can use this fact to see if an object is some specific type. The following code demonstrates how to implement the Delphi statement above in HLA:

      mov( ptrToNumeric, esi );      if( (type uint [esi])._pVMT_ = &uint._VMT_ ) then           .           .           .      endif; 

This if statement simply compares the object's _pVMT_ field (the pointer to the VMT) against the address of the desired classes' VMT. If they are equal, then the ptrToNumeric variable points at an object of type uint.

Within the body of a class method or iterator, there is a slightly easier way to see if the object is a certain class. Remember, upon entry into a method or an iterator, the EDI register contains the address of the virtual method table. Therefore, assuming you haven't modified EDI's value, you can easily test to see if this (ESI) is a specific class type using an if statement like the following:

      if( EDI = &uint._VMT_ ) then           .           .           .      endif; 

Remember, however, that EDI will only contain a pointer to the VMT when you call a class method. This is not the case when calling a class procedure.




The Art of Assembly Language
The Art of Assembly Language
ISBN: 1593272073
EAN: 2147483647
Year: 2005
Pages: 246
Authors: Randall Hyde

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net