- Run Time Type Identification (RTTI) provides some information about objects
at run time such as the name of its type
- C++ provides two basic mechanisms to obtain and use information about an
objects data type: The typeid() operator and associated
typeinfo class, and the dynamic_cast<> operator.
- The typeid() operator returns a typeinfo object which
contains information of the relevant object's data type. The typeinfo
object may be queried to obtain the information stored in it.
- In order to query the typeinfo object one must call the relevant
member function. Each typeinfo object contains the following member
functions:
int operator==(const typeinfo rhs) const; // test for equality
int operator!=(const typeinfo rhs) const; // test for inequality
before(const typeinfo rhs); // test for collating precedence
const char * name() const; // retrieve object type as string
- The most useful query function is name() which returns a const pointer to a string that describes the object's type:
using namespace std;
#include <iostream>
#include <typeinfo>
#include <string>
class Base{
public:
Base() : i(100){}
virtual void show() { cout << "i = " << i << endl; }
private:
int i;
};
class Derived : public Base{
public:
Derived() : j(1000){}
void show() { Base::show();
cout << "j = " << j << endl; }
private:
int j;
};
int main(){
char inchar;
Base* bp;
cout << "Select object type (B)ase, (D)erived: " ;
cin >> inchar;
switch(inchar){
case 'B':
bp = new Base;
break;
case 'D':
bp = new Derived;
break;
}
const char* ObjTypeName;
cout << "The Object type is: ";
ObjTypeName = typeid(*bp).name();
cout << ObjTypeName << endl;
cout << ObjTypeName+1 << endl;
return(0);
}
- It is legal and sometimes necessary to cast a derived class pointer into
base class pointer. This is also called upcast, but by doing so the type
information of the pointer gets lost.
Downcasting the pointer back to derived class requires run-time type
identification (RTTI). C++ supports RTTI for polymorphic classes as they go
through dynamic-binding and have type information associated with them.
The dynamic_cast operator returns a valid pointer if the object is of the
expected derived type otherwise it returns a null pointer. The syntax looks
like:
Derived *d_ptr = dynamic_cast < Derived * > (ptr);
This will result into an assignment if the object pointed to by ptr is of type
Derived, otherwise d_ptr will become equal to NULL.
RTTI is used when it is necessary to navigate the class hierarchy. This will
occur when some code is written in terms of 'base' class (interface) but
specialized versions of this base class are to be used through derivation:
using namespace std;
#include <iostream>
#include <string>
typedef char* String;
class Base{
public:
Base();
virtual ~Base();
virtual String getmember();
protected:
String name;
};
class Derived : public Base{
public:
Derived();
~Derived();
String getmember();
String getID();
protected:
String name;
String id;
};
Base::Base(){
cout << "Constructing Base..." << endl;
name = new char[strlen("Base") + 1];
strcpy(name, "Base");
}
Base::~Base(){
cout << "Destroying Base..." << endl;
delete name;
}
String Base::getmember(){
return name;
}
Derived::Derived(){
cout << "Constructing Derived..." << endl;
name = new char[strlen("Derived") + 1];
strcpy(name, "Derived");
id = new char[strlen("007") + 1];
strcpy(id, "007");
}
Derived::~Derived(){
cout << "Destroying Derived..." << endl;
delete name;
delete id;
}
String Derived::getmember(){
return name;
}
String Derived::getID(){
return id;
}
int main(){
int input;
Base* bptr;
cout << "Enter Object Type (1, 0): ";
cin >> input;
switch(input){
case 0: bptr = new Base;
break;
case 1: bptr = new Derived;
break;
}
cout << bptr->getmember() << endl;
if(Derived* dptr = dynamic_cast<Derived*>bptr))
cout << dptr->getID() << endl;
delete bptr;
return(0);
}
Back to Previous Page