Unabhängig vom Compiler können Sie jederzeit Laufzeit sparen, wenn Sie es sich leisten können
if (typeid(a) == typeid(b)) {
B* ba = static_cast<B*>(&a);
etc;
}
anstatt
B* ba = dynamic_cast<B*>(&a);
if (ba) {
etc;
}
Ersteres beinhaltet nur einen Vergleich von std::type_info
; Letzteres beinhaltet notwendigerweise das Durchlaufen eines Vererbungsbaums plus Vergleiche.
Darüber hinaus ... wie jeder sagt, ist die Ressourcennutzung implementierungsspezifisch.
Ich stimme den Kommentaren aller anderen zu, dass der Einreicher RTTI aus Designgründen vermeiden sollte. Es gibt jedoch gute Gründe, RTTI zu verwenden (hauptsächlich wegen boost :: any). Vor diesem Hintergrund ist es hilfreich, die tatsächliche Ressourcennutzung in gängigen Implementierungen zu kennen.
Ich habe kürzlich eine Reihe von Untersuchungen zu RTTI in GCC durchgeführt.
tl; dr: RTTI in GCC verwendet vernachlässigbaren Speicherplatz und typeid(a) == typeid(b)
ist auf vielen Plattformen (Linux, BSD und möglicherweise eingebettete Plattformen, aber nicht mingw32) sehr schnell. Wenn Sie wissen, dass Sie immer auf einer gesegneten Plattform sind, ist RTTI nahezu kostenlos.
Grobe Details:
GCC bevorzugt die Verwendung eines bestimmten "herstellerneutralen" C ++ - ABI [1] und verwendet diesen ABI immer für Linux- und BSD-Ziele [2]. Gibt für Plattformen, die diesen ABI und auch eine schwache Verknüpfung unterstützen, typeid()
ein konsistentes und eindeutiges Objekt für jeden Typ zurück, auch über dynamische Verknüpfungsgrenzen hinweg. Sie können testen &typeid(a) == &typeid(b)
oder sich einfach darauf verlassen, dass der tragbare Test typeid(a) == typeid(b)
tatsächlich nur einen Zeiger intern vergleicht.
In GCCs bevorzugter ABI enthält eine Klasse vtable immer einen Zeiger auf eine RTTI-Struktur pro Typ, obwohl sie möglicherweise nicht verwendet wird. Ein typeid()
Aufruf selbst sollte also nur so viel kosten wie jede andere vtable-Suche (genau wie das Aufrufen einer virtuellen Member-Funktion), und die RTTI-Unterstützung sollte keinen zusätzlichen Speicherplatz für jedes Objekt verwenden.
Soweit ich das beurteilen kann, enthalten die von GCC verwendeten RTTI-Strukturen (dies sind alle Unterklassen von std::type_info
) neben dem Namen nur wenige Bytes für jeden Typ. Mir ist nicht klar, ob die Namen im Ausgabecode auch mit vorhanden sind -fno-rtti
. In beiden Fällen sollte die Änderung der Größe der kompilierten Binärdatei die Änderung der Laufzeitspeichernutzung widerspiegeln.
Ein kurzes Experiment (unter Verwendung von GCC 4.4.3 unter Ubuntu 10.04 64-Bit) zeigt, dass die Binärgröße eines einfachen Testprogramms -fno-rtti
tatsächlich um einige hundert Bytes erhöht wird . Dies geschieht konsistent über Kombinationen von -g
und -O3
. Ich bin mir nicht sicher, warum die Größe zunehmen würde; Eine Möglichkeit besteht darin, dass sich der STL-Code von GCC ohne RTTI anders verhält (da Ausnahmen nicht funktionieren).
[1] Bekannt als Itanium C ++ ABI, dokumentiert unter http://www.codesourcery.com/public/cxx-abi/abi.html . Die Namen sind schrecklich verwirrend: Der Name bezieht sich auf die ursprüngliche Entwicklungsarchitektur, obwohl die ABI-Spezifikation auf vielen Architekturen einschließlich i686 / x86_64 funktioniert. Kommentare in der internen Quelle und im STL-Code von GCC beziehen sich auf Itanium als "neuen" ABI im Gegensatz zu dem "alten", den sie zuvor verwendet haben. Schlimmer noch, der "neue" / Itanium ABI bezieht sich auf alle Versionen, die über erhältlich sind -fabi-version
. Das "alte" ABI war älter als diese Versionierung. GCC hat das Itanium / versioned / "new" ABI in Version 3.0 übernommen. Das "alte" ABI wurde in Version 2.95 und früher verwendet, wenn ich ihre Änderungsprotokolle richtig lese.
[2] Ich konnte keine Ressourcen finden, die die std::type_info
Objektstabilität nach Plattform auflisten . Für Compiler, auf die ich Zugriff hatte, habe ich Folgendes verwendet : echo "#include <typeinfo>" | gcc -E -dM -x c++ -c - | grep GXX_MERGED_TYPEINFO_NAMES
. Dieses Makro steuert das Verhalten von operator==
for std::type_info
in der STL von GCC ab GCC 3.0. Ich habe festgestellt, dass mingw32-gcc dem Windows C ++ - ABI folgt, bei dem std::type_info
Objekte für einen Typ in DLLs nicht eindeutig sind. typeid(a) == typeid(b)
Anrufe strcmp
unter der Decke. Ich spekuliere, dass auf eingebetteten Einzelprogrammzielen wie AVR, bei denen es keinen Code zum Verknüpfen gibt, std::type_info
Objekte immer stabil sind.