Run-time type informationIn computer programming, run-time type information or run-time type identification (RTTI)[1] is a feature of some programming languages (such as C++,[2] Object Pascal, and Ada[3]) that exposes information about an object's data type at runtime. Run-time type information may be available for all types or only to types that explicitly have it (as is the case with Ada). Run-time type information is a specialization of a more general concept called type introspection. In the original C++ design, Bjarne Stroustrup did not include run-time type information, because he thought this mechanism was often misused.[4] OverviewIn C++, RTTI can be used to do safe typecasts using the RTTI is available only for classes that are polymorphic, which means they have at least one virtual method. In practice, this is not a limitation because base classes must have a virtual destructor to allow objects of derived classes to perform proper cleanup if they are deleted from a base pointer. Some compilers have flags to disable RTTI. Using these flags may reduce the overall size of the application, making them especially useful when targeting systems with a limited amount of memory.[7] C++ – typeidThe Objects of class Example#include <iostream>
#include <typeinfo>
class Person {
public:
virtual ~Person() = default;
};
class Employee : public Person {};
int main() {
Person person;
Employee employee;
Person* ptr = &employee;
Person& ref = employee;
// The string returned by typeid::name is implementation-defined.
std::cout << typeid(person).name()
<< std::endl; // Person (statically known at compile-time).
std::cout << typeid(employee).name()
<< std::endl; // Employee (statically known at compile-time).
std::cout << typeid(ptr).name()
<< std::endl; // Person* (statically known at compile-time).
std::cout << typeid(*ptr).name()
<< std::endl; // Employee (looked up dynamically at run-time
// because it is the dereference of a
// pointer to a polymorphic class).
std::cout << typeid(ref).name()
<< std::endl; // Employee (references can also be polymorphic)
Person* p = nullptr;
try {
typeid(*p); // Not undefined behavior; throws std::bad_typeid.
} catch (...) { }
Person& p_ref = *p; // Undefined behavior: dereferencing null
typeid(p_ref); // does not meet requirements to throw std::bad_typeid
// because the expression for typeid is not the result
// of applying the unary * operator.
}
Output (exact output varies by system and compiler): Person Employee Person* Employee Employee C++ – dynamic_cast and Java castThe A Java typecast behaves similarly; if the object being cast is not actually an instance of the target type, and cannot be converted to one by a language-defined method, an instance of ExampleSuppose some function takes an object of type #include <array>
#include <iostream>
#include <memory>
#include <typeinfo>
using namespace std;
class A {
public:
// Since RTTI is included in the virtual method table there should be at
// least one virtual function.
virtual ~A() = default;
void MethodSpecificToA() {
cout << "Method specific for A was invoked" << endl;
}
};
class B: public A {
public:
void MethodSpecificToB() {
cout << "Method specific for B was invoked" << endl;
}
};
void MyFunction(A& my_a) {
try {
// Cast will be successful only for B type objects.
B& my_b = dynamic_cast<B&>(my_a);
my_b.MethodSpecificToB();
} catch (const bad_cast& e) {
cerr << " Exception " << e.what() << " thrown." << endl;
cerr << " Object is not of type B" << endl;
}
}
int main() {
array<unique_ptr<A>, 3> array_of_a; // Array of pointers to base class A.
array_of_a[0] = make_unique<B>(); // Pointer to B object.
array_of_a[1] = make_unique<B>(); // Pointer to B object.
array_of_a[2] = make_unique<A>(); // Pointer to A object.
for (int i = 0; i < 3; ++i)
MyFunction(*array_of_a[i]);
}
Console output: Method specific for B was invoked Method specific for B was invoked Exception std::bad_cast thrown. Object is not of type B A similar version of void MyFunction(A* my_a) {
B* my_b = dynamic_cast<B*>(my_a);
if (my_b != nullptr)
my_b->methodSpecificToB();
else
std::cerr << " Object is not B type" << std::endl;
}
Object Pascal, DelphiIn Object Pascal and Delphi, the operator The RTTI unit is used to manipulate object type information at run time. This unit contains a set of classes that allow you to: get information about an object's class and its ancestors, properties, methods and events, change property values and call methods. The following example shows the use of the RTTI module to obtain information about the class to which an object belongs, creating it, and to call its method. The example assumes that the TSubject class has been declared in a unit named SubjectUnit. uses
RTTI, SubjectUnit;
procedure WithoutReflection;
var
MySubject: TSubject;
begin
MySubject := TSubject.Create;
try
Subject.Hello;
finally
Subject.Free;
end;
end;
procedure WithReflection;
var
RttiContext: TRttiContext;
RttiType: TRttiInstanceType;
Subject: TObject;
begin
RttiType := RttiContext.FindType('SubjectUnit.TSubject') as TRttiInstanceType;
Subject := RttiType.GetMethod('Create').Invoke(RttiType.MetaclassType, []).AsObject;
try
RttiType.GetMethod('Hello').Invoke(Subject, []);
finally
Subject.Free;
end;
end;
See alsoReferences
External linksInformation related to Run-time type information |