C++ Programming/RTTI

From Wikibooks, the open-content textbooks collection

Jump to: navigation, search

Contents

[edit] Run-Time Type Information (RTTI)

RTTI refers to the ability of the system to report on the dynamic type of an object and to provide information about that type at runtime (as opposed to at compile time).

[edit] dynamic_cast

dynamic_cast allows down-casts of polymorphic types—in other words casting a base type to a type lower in the hierarchy.

object_of_target_type* ptr = dynamic_cast<target_type*>(pointer_expression);
object_of_target_type& ref = dynamic_cast<target_type&>(reference_expression);

Let's say that we have the following class hierarchy:

class Interface
{
public:
        virtual void GenericOp() = 0;
};
 
class SpecificClass : public Interface
{
public:
        virtual void GenericOp();
        virtual void SpecificOp();
};

Let's say that we also have a pointer of type Interface*, like so:

Interface* ptr_interface;

But suppose that we know for sure that this pointer points to an object of type SpecificClass, and we would like to call the member SpecificOp() of that class. To dynamically convert to a derived type we can use dynamic_cast, like so:

SpecificClass* ptr_specific = dynamic_cast<SpecificClass*>(ptr_interface);

With this statement, the program converts the base class pointer to a derived class pointer and allows the derived class members to be called. Be very careful, however: if the pointer that you are trying to cast is not of the correct type, then dynamic_cast will return a null pointer.

We can also use dynamic_cast with references.

SpecificClass& ref_specific = dynamic_cast<SpecificClass&>(ref_interface);

This works almost in the same way as pointers. However, if the real type of the object being cast is not correct then dynamic_cast will not return null (there's no such thing as a null reference). Instead, it will throw a std::bad_cast exception.

[edit] typeid

The typeid operator returns information about a specific type. Its RTTI use looks like

const std::type_info& info = typeid(object_expression);

Sometimes we need to know the exact type of an object. The typeid operator returns a reference to a standard class std::type_info that contains information about the type. This class provides some useful members including the == and != operators. The most interesting method is probably:

const char* std::type_info::name() const;

This member function returns a pointer to a C-style string with the name of the object type. For example, using the classes from our earlier example:

const std::type_info &info = typeid(ptr_interface);
std::cout << info.name() << std::endl;

This program would print SpecificClass because that is the dynamic type of the pointer ptr_interface.

typeid is actually an operator rather than a function, as it can also act on types:

const std::type_info& info = typeid(type);

for example (and somewhat circularly)

const std::type_info& info = typeid(std::type_info);

will give a type_info object which describes type_info objects. This latter use is not RTTI, but rather CTTI (compile-time type identification).

[edit] Limitations

There are some limitations to RTTI. First, RTTI can only be used with polymorphic types. That means that your classes must have at least one virtual function, either directly or through inheritance. Second, because of the additional information required to store types some compilers require a special switch to enable RTTI.

Note that references to pointers will not work under RTTI:

void example( int*& refptrTest )
{
        std::cout << "What type is *&refptrTest : " << typeid( refptrTest ).name() << std::endl;
}

Will report int*, as typeid() does not support reference types.

[edit] Misuses of RTTI

RTTI should only be used sparingly in C++ programs. There are several reasons for this. Most importantly, other language mechanisms such as polymorphism and templates are almost always superior to RTTI. As with everything, there are exceptions, but the usual rule concerning RTTI is more or less the same as with goto statements. Do not use it as a shortcut around proper, more robust design. Only use RTTI if you have a very good reason to do so and only use it if you know what you are doing.