Runtime Type Information (frequentemente abreviado para RTTI; Informação de Tipo [de Dado] em Tempo de Execução em inglês) é uma técnica disponível em algumas linguagens de programação e que consiste em manter informação sobre o tipo de dado de um objeto em memória durante o tempo de execução de um programa de computador. Algumas implementações limitam-se a manter somente a árvore de heranças da classe enquanto outras também incluem informações dos métodos do objeto e seus atributos.
Apesar de disponível em várias linguagens, o termo RTTI é tipicamente utilizado somente em discussões do C++. Para utilizar o operadores dynamic_cast<>
ou type_info
, o RTTI deve estar ativado. O seguinte exemplo ilustra a técnica:
class base
{
virtual ~base(){}
};
class derivada : public base
{
public:
virtual ~derivada(){}
int compare(derived &ref);
};
int meu_comparador_para_ordenacao_generica(base &ref1, base &ref2)
{
derivada &d = dynamic_cast<derivada &>(ref1); // RTTI é usado aqui
return d.compare(dynamic_cast<derivada &>(ref2));
}
Na linha indicada o RTTI habilita o processo de lançar a exceção bad_cast
caso a conversão de tipo não for possível. Note que é impossível obter tal informação em tempo de compilação, por isso a utilização de uma estrutura em tempo de execução para realizar tal tarefa.
O Delphi também disponibiliza uma forma do RTTI, que permite determinar se um objeto é de uma classe ou de suas derivações. Para isso são usados os operadores is
, que verifica o tipo, e as
, que verifica a conversão do tipo.
O RTTI provê um modo de determinar se o tipo de um objeto é de uma classe em particular ou de um dos seus descendentes. Os operadores ‘is’ e ‘as’ geralmente usados na linguagem Delphi, baseiam-se de alguma forma na presença do RTTI. O operador ‘is’, que executa dinamicamente a verificação de tipo, é usado para verificar a classe atual de um objeto em tempo de execução.
O seguinte exemplo ilustra a técnica[1]:
procedure TFormulario.Button1Click(Sender: TObject) ;
var
ClassRef: TClass;
begin
MyListBox.Clear;
ClassRef := Sender.ClassType;
while ClassRef <> nil do
begin
MyListBox.Items.Add(ClassRef.ClassName) ;
ClassRef := ClassRef.ClassParent;
end;
end;
No exemplo acima, a rotina listará a árvore de herança desde a classe TButton
até a classe TObject
.