Quel que soit le compilateur, vous pouvez toujours économiser sur l'exécution si vous pouvez vous permettre de le faire
if (typeid(a) == typeid(b)) {
B* ba = static_cast<B*>(&a);
etc;
}
au lieu de
B* ba = dynamic_cast<B*>(&a);
if (ba) {
etc;
}
Le premier implique une seule comparaison de std::type_info
; ce dernier implique nécessairement de parcourir un arbre d'héritage plus des comparaisons.
Au-delà ... comme tout le monde le dit, l'utilisation des ressources est spécifique à l'implémentation.
Je suis d'accord avec les commentaires de tous les autres selon lesquels l'auteur de la proposition devrait éviter le RTTI pour des raisons de conception. Cependant, il y a de bonnes raisons d'utiliser RTTI (principalement à cause de boost :: any). Cela à l'esprit, il est utile de connaître son utilisation réelle des ressources dans les implémentations courantes.
J'ai récemment fait un tas de recherches sur RTTI dans GCC.
tl; dr: RTTI dans GCC utilise un espace négligeable et typeid(a) == typeid(b)
est très rapide, sur de nombreuses plates-formes (Linux, BSD et peut-être plates-formes embarquées, mais pas mingw32). Si vous savez que vous serez toujours sur une plate-forme bénie, RTTI est très proche de la gratuité.
Détails granuleux:
GCC préfère utiliser un ABI C ++ "indépendant du fournisseur" [1], et utilise toujours cet ABI pour les cibles Linux et BSD [2]. Pour les plates-formes qui prennent en charge cette ABI et également une liaison faible, typeid()
renvoie un objet cohérent et unique pour chaque type, même au-delà des limites de liaison dynamique. Vous pouvez tester &typeid(a) == &typeid(b)
, ou simplement vous fier au fait que le test portable typeid(a) == typeid(b)
compare simplement un pointeur en interne.
Dans l'ABI préférée de GCC, une table vtable de classe contient toujours un pointeur vers une structure RTTI par type, bien qu'elle puisse ne pas être utilisée. Ainsi, un typeid()
appel lui-même ne devrait coûter autant que toute autre recherche de vtable (le même que l'appel d'une fonction membre virtuelle), et le support RTTI ne devrait pas utiliser d'espace supplémentaire pour chaque objet.
D'après ce que je peux comprendre, les structures RTTI utilisées par GCC (ce sont toutes les sous-classes de std::type_info
) ne contiennent que quelques octets pour chaque type, à part le nom. Il n'est pas clair pour moi si les noms sont présents dans le code de sortie, même avec -fno-rtti
. Dans tous les cas, le changement de taille du binaire compilé doit refléter le changement d'utilisation de la mémoire d'exécution.
Une expérience rapide (en utilisant GCC 4.4.3 sur Ubuntu 10.04 64 bits) montre que cela augmente en-fno-rtti
fait la taille binaire d'un programme de test simple de quelques centaines d'octets. Cela se produit de manière cohérente dans les combinaisons de et . Je ne sais pas pourquoi la taille augmenterait; une possibilité est que le code STL de GCC se comporte différemment sans RTTI (puisque les exceptions ne fonctionneront pas).-g
-O3
[1] Connu sous le nom d'Itanium C ++ ABI, documenté à http://www.codesourcery.com/public/cxx-abi/abi.html . Les noms sont horriblement déroutants: le nom fait référence à l'architecture de développement d'origine, bien que la spécification ABI fonctionne sur de nombreuses architectures, y compris i686 / x86_64. Les commentaires dans la source interne de GCC et dans le code STL font référence à Itanium comme étant la "nouvelle" ABI contrairement à l '"ancienne" qu'ils utilisaient auparavant. Pire encore, le «nouveau» / Itanium ABI fait référence à toutes les versions disponibles via -fabi-version
; «l'ancienne» ABI était antérieure à cette gestion des versions. GCC a adopté l'ABI Itanium / versioned / "new" dans la version 3.0; l '«ancien» ABI a été utilisé en 2.95 et avant, si je lis correctement leurs changelogs.
[2] Je n'ai trouvé aucune ressource répertoriant std::type_info
la stabilité des objets par plateforme. Pour les compilateurs J'ai eu accès, je suit: echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES
. Cette macro contrôle le comportement de operator==
for std::type_info
dans la STL de GCC, à partir de GCC 3.0. J'ai trouvé que mingw32-gcc obéit à l'ABI Windows C ++, où les std::type_info
objets ne sont pas uniques pour un type parmi les DLL; typeid(a) == typeid(b)
appels strcmp
sous les couvertures. Je suppose que sur les cibles intégrées à programme unique comme AVR, où il n'y a pas de code à lier, les std::type_info
objets sont toujours stables.