C++ Typecasting Part 2 – RTTI, dynamic_cast, typeid and type_info

Before you start this C++ programming tutorial on RTTI, dynamic_cast, typeid and type_info,
make sure you fully understand the previous tutorial on static_cast, const_cast and reinterpret_cast.

Runtime Type Information (RTTI)

Runtime Type Information (RTTI) is the concept of determining the type of any variable during execution (runtime.) The RTTI mechanism contains:

  • The operator dynamic_cast
  • The operator typeid
  • The struct type_info

RTTI can only be used with polymorphic types. This means that with each class you make, you must have at least one virtual function (either directly or through inheritance.)

Compatibility note: On some compilers you have to enable support of RTTI to keep track of dynamic types.
So to make use of dynamic_cast (see next section) you have to enable this feature. See you compiler documentation for more detail.

Dynamic_cast

The dynamic_cast can only be used with pointers and references to objects. It makes sure that the result of the type conversion is valid and complete object of the requested class. This is way a dynamic_cast will always be successful if we use it to cast a class to one of its base classes. Take a look at the example:


	class Base_Class { };
	class Derived_Class: public Base_Class { };

	Base_Class a; Base_Class * ptr_a;
	Derived_Class b; Derived_Class * ptr_b;

	ptr_a = dynamic_cast<Base_Class *>(&b);
	ptr_b = dynamic_cast<Derived_Class *>(&a);

The first dynamic_cast statement will work because we cast from derived to base. The second dynamic_cast statement will produce a compilation error because base to derived conversion is not allowed with dynamic_cast unless the base class is polymorphic.

If a class is polymorphic then dynamic_cast will perform a special check during execution. This check ensures that the expression is a valid and complete object of the requested class.
Take a look at the example:


// dynamic_cast
#include <iostream>
#include <exception>
using namespace std;

class Base_Class { virtual void dummy() {} };
class Derived_Class: public Base_Class { int a; };

int main () {
  try {
 	Base_Class * ptr_a = new Derived_Class;
 	Base_Class * ptr_b = new Base_Class;
 	Derived_Class * ptr_c;

    	ptr_c = dynamic_cast< Derived_Class *>(ptr_a);
    	if (ptr_c ==0) cout << "Null pointer on first type-cast" << endl;

    	ptr_c = dynamic_cast< Derived_Class *>(ptr_b);
    	if (ptr_c ==0) cout << "Null pointer on second type-cast" << endl;

  	} catch (exception& my_ex) {cout << "Exception: " << my_ex.what();}
  return 0;
}

In the example we perform two dynamic_casts from pointer objects of type Base_Class* (namely ptr_a and ptr_b) to a pointer object of type Derived_Class*.

If everything goes well then the first one should be successful and the second one will fail. The pointers ptr_a and ptr_b are both of the type Base_Class. The pointer ptr_a points to an object of the type Derived_Class. The pointer ptr_b points to an object of the type Base_Class. So when the dynamic type cast is performed then ptr_a is pointing to a full object of class Derived_Class, but the pointer ptr_b points to an object of class Base_Class. This object is an incomplete object of class Derived_Class; thus this cast will fail!

Because this dynamic_cast fails a null pointer is returned to indicate a failure. When a reference type is converted with dynamic_cast and the conversion fails then there will be an exception thrown out instead of the null pointer. The exception will be of the type bad_cast.

With dynamic_cast it is also possible to cast null pointers even between the pointers of unrelated classes.
Dynamic_cast can cast pointers of any type to void pointer(void*).

Typeid and typ_info

If a class hierarchy is used then the programmer doesn’t have to worry (in most cases) about the data-type of a pointer or reference, because the polymorphic mechanism takes care of it. In some cases the programmer wants to know if an object of a derived class is used. Then the programmer can make use of dynamic_cast. (If the dynamic cast is successful, then the pointer will point to an object of a derived class or to a class that is derived from that derived class.) But there are circumstances that the programmer (not often) wants to know the prizes data-type. Then the programmer can use the typeid operator.

The typeid operator can be used with:

  • Variables
  • Expressions
  • Data-types

Take a look at the typeid example:


	#include <iostream>
	#include <typeinfo>
	using namespace std;

	int main ()
	{
		int * a;
		int b; 

		a=0; b=0;
		if (typeid(a) != typeid(b))
		{
			cout << "a and b are of different types:\n";
			cout << "a is: " << typeid(a).name() << '\n';
			cout << "b is: " << typeid(b).name() << '\n';
		}
		return 0;
	 }

Note: the extra header file typeinfo.

The result of a typeid is a const type_info&. The class type_info is part of the standard C++ library and contains information about data-types. (This information can be different. It all depends on how it is implemented.)

A bad_typeid exception is thrown by typeid, if the type that is evaluated by typeid is a pointer that is preceded by a dereference operator and that pointer has a null value.

That is all for this tutorial. In the next C++ programming tutorial we will take a look at pre-processors.

This entry was posted in C++ Tutorials. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site. Tweet This! Tweet This! or use to share this post with others.

There are currently 10 responses to “C++ Typecasting Part 2 – RTTI, dynamic_cast, typeid and type_info”

Why not let us know what you think by adding your own comment!

  1. Kumar Santosh on June 7th, 2010:

    dynamic_cast comes at price, so one should be moderate in choosing the typeid and dynamic_cast. because, dynamic_cast has to traverse the entire hierarchy to determine the type of the object.

  2. admin on June 7th, 2010:

    Yes, you are right, dynamic_casts comes at a price. A good rule is to do type checking that can take place at compile time than at run-time. Further more early type checking ensures faster execution time and in most cases a smaller executable. (Also in most cases, early type checking ensures early error detection, this can be even more important than the previous two!) But you should never overdo dynamic_casts! So if you find yourself using dynamic_cast extensively, you should always take another look at your applications design.

  3. shilpa on November 20th, 2010:

    thanks for this explanation.i am searched many websites but i have not get like this point detail explanation.

  4. Anish Jain on March 5th, 2011:

    i like it man ….

  5. Sonia on April 29th, 2011:

    i like this detail explanation.thanks

  6. Amu on May 9th, 2011:

    how exactly typeid is returning type_info&?.. In the type_info class constructor is in private mode..

  7. yathri on October 7th, 2011:

    its super but need more information thanks

  8. ABDUL on December 8th, 2011:

    SOOOOOOOOOOOOOOOOOOOOPPPPEEER!!

  9. shibbu on April 30th, 2013:

    Good Article..

  10. amit on May 4th, 2013:

    nice ,

    can u please explain static cast between structure and integer type

Leave a Reply: