Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Use RTTI for Dynamic Type Identification : Page 3

Runtime Type Information (RTTI) was created more than a decade ago, yet most developers remain unaware of its functions and benefits. This month's solution explains when and how you can use RTTI for dynamic type detection.




Full Text Search: The Key to Better Natural Language Queries for NoSQL in Node.js

Date: 1/31/2018 @ 2 p.m. ET

Using RTTI
To customize the menu dynamically, the file manager has to probe each files dynamic type.

Operator typeid
Operator typeid retrieves the runtime type information associated with a certain object. typeid takes an object or a type name as its argument. Thus, to determine if the dynamic type of x is Y, check whether the expression typeid(x) == typeid(Y) is true:

#include <typeinfo> // needed for typeid void menu::build(const File * pfile) { if (typeid(*pfile)==typeid(TextFile)) { add_option("edit"); } else if (typeid(*pfile)==typeid(MediaFile)) { add_option("play"); } }

TIP: Certain compilers, such as Visual C++, disable RTTI by default to eliminate performance overhead. If your program does use RTTI, remember to enable RTTI before compilation.

The use of typeid might introduce maintenance problems in the future. Suppose you decide to extend the class hierarchy and derive another class from MediaFile called LocalizedMedia that represents a media file with subtitles in various languages. Yet in essence, a LocalizedMedia file is a MediaFile. Therefore, the file manager should display the "play" option when the user right clicks on a LocalizedMedia file. Unfortunately, the build() member function will fail to do so because you didnt include a test for this particular file type. To fix this, you can patch it like this:

void menu::build(const File * pfile) { //.. else if (typeid(*pfile)==typeid(LocalizedMedia)) { add_option("play"); } }

Alas, this function will have to be patched every time you add a new class. Clearly, this isn't an ideal solution.

Operator dynamic_cast
You need a way to determine whether a certain object is a MediaFile or any class derived from it. This is exactly what operator dynamic_cast does. dynamic_cast takes two arguments: a type name and a pointer or a reference to a polymorphic object. It attempts to cast at runtime the object to the target type and returns the result. Put differently, if the function succeeds in casting *pfile to MediaFile dynamically, then pfile's dynamic type is MediaFile or a class derived from it. Otherwise, pfile is a different beast:

void menu::build(const File * pfile) { if (dynamic_cast <MediaFile *> (pfile)) { // pfile is MediaFile or LocalizedMedia add_option("play"); } else if (dynamic_cast <TextFile*> (pfile)) { // pfile is a TextFile or a class derived from it add_option("edit"); } }

Moderation is Advised
Although the use of dynamic_cast solves this problem neatly, it exacts a toll. As opposed to typeid, a dynamic cast isn't a constant time operation. In order to determine whether the cast can be performed, dynamic_cast must traverse the derivation lattice of its argument at runtime. Therefore, use dynamic_cast judiciously.

Danny Kalev is a system analyst and software engineer with 13 years of experience, specializing in C++ and object-oriented analysis and design. He was a member of the ANSI C++ standardization committee between 1997-2001. Danny is the author of ANSI/ISO C++ Professional Programmer's Handbook (Que, 1999, ISBN: 0789720221). Check out the DevX review here. He can be reached at dannykk@inter.net.il.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date