2015-12-18 6 views
13

C++ - Code kann mit deaktivierter Laufzeittypinformation kompiliert werden, wodurch dynamic_cast deaktiviert wird. Virtuelle (polymorphe) Methoden müssen jedoch basierend auf dem Laufzeittyp des Ziels weiterhin bereitgestellt werden. Bedeutet das nicht, dass die Typinformation sowieso vorhanden ist, und dynamic_cast sollte immer funktionieren können?Keine RTTI, aber immer noch virtuelle Methoden

+1

Meine Vermutung wäre, dass die vtable noch vorhanden ist, aber da es keine Typinformationen (nur Funktionszeiger) enthält, funktionieren virtuelle Funktionen immer noch. –

+1

Mögliches Duplikat von http://stackoverflow.com/questions/4486609/when-can-compiling-c-without-rtti-cause-problems ...? –

+0

Damit dynamic_cast funktioniert (in komplexen Fällen mit mehrfacher Vererbung) benötigen Sie etwas mehr als virtuelle Funktionstabellen – marom

Antwort

13

Das Deaktivieren von RTTI beendet dynamic_cast und typeid, hat aber keine Auswirkungen auf virtuelle Funktionen. Virtuelle Funktionen werden über die "vtable" von Klassen gesendet, die virtuelle Funktionen haben; Wenn Sie eine vtable vermeiden möchten, können Sie einfach keine virtuellen Funktionen haben.

Viele C++ Code in der freien Natur ohne dynamic_cast arbeiten kann und fast alles davon kann ohne typeid arbeiten, aber relativ wenig C++ Anwendungen würden ohne virtuelle Funktionen (oder mehr auf den Punkt überleben, erwartete Funktionen, die sie virtuell sein wird nicht virtuell).

Eine virtuelle Tabelle (vtable) ist nur ein per-instance-Zeiger auf eine Suchtyp-Tabelle für alle virtuellen Funktionen. Sie zahlen nur für das, was Sie verwenden (Bjarne liebt diese Philosophie und widersetzte sich zunächst RTTI). Bei voller RTTI hingegen enden Ihre Bibliotheken und ausführbaren Dateien mit einer Menge ausgeklügelter Strings und anderer Informationen, die eingebacken sind, um den Namen jedes Typs und vielleicht andere Dinge wie die hierarchischen Beziehungen zwischen Typen zu beschreiben.

Ich habe Produktionssysteme gesehen, bei denen das Deaktivieren von RTTI die Größe ausführbarer Dateien um 50% verringerte. Das meiste davon war aufgrund der massiven String-Namen, die in einigen C++ - Programmen, die Vorlagen stark verwenden, enden.

+0

Ok, so dass 'dynamic_cast' weitere Informationen benötigt. Aber es klingt wie 'typeid' könnte immer noch funktionieren, zumindest für Typen, die sowieso eine vtable haben. Kann der Vtable-Zeiger manuell aus C++ - Code aufgerufen werden? –

+0

'typeid' kann nicht funktionieren, weil einer seiner Hauptzwecke darin besteht, für jeden Typ einen Namen anzugeben, und diese Namen (die tatsächlichen nullterminierten Strings) werden einfach nicht ohne RTTI in Objektdateien ausgegeben. Und nein, auf die Vtable kann in C++ nicht manuell zugegriffen werden. Es kann plattformspezifische Möglichkeiten geben, aber selbst das ist selten IMO. –

+0

Oh, tschuldigung. :) Ich nahm an, ohne zu überprüfen, dass "typeid" irgendeine Art von schrägem Integer/Zeiger zurückgibt. Macht Sinn, dass es nicht funktioniert, wenn es ein String ist (edit: eigentlich 'class type_info'). –

Verwandte Themen