Independentemente do compilador, você sempre pode economizar em tempo de execução, se puder fazer isso
if (typeid(a) == typeid(b)) {
B* ba = static_cast<B*>(&a);
etc;
}
ao invés de
B* ba = dynamic_cast<B*>(&a);
if (ba) {
etc;
}
O primeiro envolve apenas uma comparação de std::type_info
; o último envolve necessariamente atravessar uma árvore de herança mais comparações.
Além disso, como todo mundo diz, o uso de recursos é específico da implementação.
Concordo com os comentários de todos os outros de que o remetente deve evitar a RTTI por motivos de design. No entanto, não são boas razões para utilizar RTTI (principalmente por causa do boost :: houver). Isso é útil para saber o uso real de recursos em implementações comuns.
Recentemente, fiz várias pesquisas sobre RTTI no GCC.
tl; dr: RTTI no GCC usa espaço desprezível e typeid(a) == typeid(b)
é muito rápido, em muitas plataformas (Linux, BSD e talvez plataformas embarcadas, mas não no mingw32). Se você sabe que sempre estará em uma plataforma abençoada, o RTTI está muito perto de ser gratuito.
Detalhes corajosos:
O GCC prefere usar um C ++ ABI "neutro em relação ao fornecedor" [1] e sempre usa esse ABI para destinos Linux e BSD [2]. Para plataformas que suportam essa ABI e também com ligação fraca, typeid()
retorna um objeto consistente e exclusivo para cada tipo, mesmo através dos limites de vinculação dinâmica. Você pode testar &typeid(a) == &typeid(b)
ou apenas confiar no fato de que o teste portátil typeid(a) == typeid(b)
, na verdade, apenas compara um ponteiro internamente.
Na ABI preferida do GCC, uma tabela de classe sempre mantém um ponteiro para uma estrutura RTTI por tipo, embora possa não ser usada. Portanto, uma typeid()
chamada em si só deve custar tanto quanto qualquer outra pesquisa de vtable (o mesmo que chamar uma função de membro virtual) e o suporte a RTTI não deve usar espaço extra para cada objeto.
Pelo que pude entender, as estruturas RTTI usadas pelo GCC (todas essas são as subclasses de std::type_info
) contêm apenas alguns bytes para cada tipo, além do nome. Não está claro para mim se os nomes estão presentes no código de saída, mesmo com -fno-rtti
. De qualquer forma, a alteração no tamanho do binário compilado deve refletir a alteração no uso da memória de tempo de execução.
Uma experiência rápida (usando o GCC 4.4.3 no Ubuntu 10.04 de 64 bits) mostra que, -fno-rtti
na verdade, aumenta o tamanho binário de um programa de teste simples em algumas centenas de bytes. Isso acontece consistentemente nas combinações de -g
e -O3
. Não sei por que o tamanho aumentaria; uma possibilidade é que o código STL do GCC se comporte de maneira diferente sem o RTTI (já que as exceções não funcionarão).
[1] Conhecido como Itanium C ++ ABI, documentado em http://www.codesourcery.com/public/cxx-abi/abi.html . Os nomes são terrivelmente confusos: o nome se refere à arquitetura de desenvolvimento original, embora a especificação ABI funcione em várias arquiteturas, incluindo i686 / x86_64. Os comentários na fonte interna e no código STL do GCC referem-se ao Itanium como a "nova" ABI, em contraste com a "antiga" usada anteriormente. Pior, o "novo" / Itanium ABI refere-se a todas as versões disponíveis no -fabi-version
; a ABI "antiga" antecedeu esse controle de versão. O GCC adotou a ITB Itanium / versioned / "new" na versão 3.0; a ABI "antiga" foi usada na versão 2.95 e anterior, se eu estiver lendo os registros de alterações corretamente.
[2] Não consegui encontrar nenhuma std::type_info
estabilidade de objeto da lista de recursos por plataforma. Para compiladores I teve acesso, eu usei o seguinte: echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES
. Essa macro controla o comportamento de operator==
for std::type_info
no STL do GCC, a partir do GCC 3.0. Eu descobri que o mingw32-gcc obedece à ABI do Windows C ++, onde os std::type_info
objetos não são exclusivos para um tipo nas DLLs; typeid(a) == typeid(b)
chamadas strcmp
debaixo das cobertas. Especulo que em destinos incorporados de programa único como o AVR, onde não há código para vincular, os std::type_info
objetos são sempre estáveis.