dynamic_cast sollte den Trick machen
TYPE& dynamic_cast<TYPE&> (object);
TYPE* dynamic_cast<TYPE*> (object);
Das dynamic_cast
Schlüsselwort wandelt ein Datum von einem Zeiger oder Referenztyp in einen anderen um und führt eine Laufzeitprüfung durch, um die Gültigkeit der Umwandlung sicherzustellen.
Wenn Sie versuchen, einen Zeiger auf einen Typ zu erstellen, der kein Typ eines tatsächlichen Objekts ist, ist das Ergebnis der Umwandlung NULL. Wenn Sie versuchen, eine Umwandlung vorzunehmen, um auf einen Typ zu verweisen, der kein Typ eines tatsächlichen Objekts ist, löst die Umwandlung eine bad_cast
Ausnahme aus.
Stellen Sie sicher, dass in der Basisklasse mindestens eine virtuelle Funktion vorhanden ist, damit dynamic_cast funktioniert.
Wikipedia-Thema Informationen zum Laufzeit-Typ
RTTI ist nur für polymorphe Klassen verfügbar, dh sie verfügen über mindestens eine virtuelle Methode. In der Praxis ist dies keine Einschränkung, da Basisklassen über einen virtuellen Destruktor verfügen müssen, damit Objekte abgeleiteter Klassen eine ordnungsgemäße Bereinigung durchführen können, wenn sie aus einem Basiszeiger gelöscht werden.
dynamic_cast
, wenn es nicht konvertierbar ist? Gibt es eine Möglichkeit, dies zu tun, ohne einen Wurf zu generieren?A* aptr = dynamic_cast<A*>(ptr);
// soll es nicht so seinuint8_t*
? Kann ich das überprüfenuint32_t* x = dynamic_cast<uint32_t*>(p)
, wop
istuint8_t*
? (Ich versuche einen Test für Punning-Verstöße zu finden).Dynamische Besetzung ist das Beste für Ihre Beschreibung des Problems, aber ich möchte nur hinzufügen, dass Sie den Klassentyp finden können mit:
quelle
11MyClass
. Zum Entwirren können Sie die ABI-Erweiterungsbibliothek in verwendencxxabi.h
. Dies gibt Ihnen,abi::__cxa_demangle
was Ihnen den richtigen Namen geben wirdDies wird als RTTI bezeichnet , aber Sie möchten Ihr Design hier mit ziemlicher Sicherheit überdenken, da das Finden des Typs und das Ausführen spezieller Dinge darauf Ihren Code spröder macht.
quelle
Um vollständig zu sein, werde ich Robocide aufbauen und darauf hinweisen, dass
typeid
es alleine verwendet werden kann, ohne name () zu verwenden:Ausgabe:
quelle
Betten Sie wahrscheinlich ein ID- "Tag" in Ihre Objekte ein und verwenden Sie es, um zwischen Objekten der Klasse A und Objekten der Klasse B zu unterscheiden.
Dies zeigt jedoch einen Fehler im Design. Idealerweise sollten die Methoden in B, die A nicht hat, Teil von A sein, aber leer bleiben, und B überschreibt sie. Dies beseitigt den klassenspezifischen Code und ist eher im Sinne von OOP.
quelle
Du suchst nach
dynamic_cast<B*>(pointer)
quelle
Weil deine Klasse nicht polymorph ist. Versuchen:
Jetzt
BaseClas
ist polymorph. Ich habe die Klasse in struct geändert, da die Mitglieder einer struct standardmäßig öffentlich sind.quelle
Ihre Beschreibung ist etwas verwirrend.
Obwohl einige C ++ - Implementierungen Mechanismen dafür haben, sollten Sie im Allgemeinen nicht nach dem Typ fragen. Stattdessen sollten Sie einen dynamic_cast für den Zeiger auf A ausführen. Dies führt dazu, dass zur Laufzeit der tatsächliche Inhalt des Zeigers auf A überprüft wird. Wenn Sie ein B haben, erhalten Sie Ihren Zeiger auf B. Andernfalls erhalten Sie eine Ausnahme oder Null.
quelle
Wie andere angegeben haben, können Sie dynamic_cast verwenden. Wenn Sie jedoch im Allgemeinen dynamic_cast verwenden, um den Typ der abgeleiteten Klasse herauszufinden, an der Sie arbeiten, weist dies auf ein schlechtes Design hin. Wenn Sie eine Funktion überschreiben, die den Zeiger von A als Parameter verwendet, sollte sie in der Lage sein, mit den Methoden / Daten der Klasse A selbst zu arbeiten, und sollte nicht von den Daten der Klasse B abhängen. In Ihrem Fall, anstatt sie zu überschreiben Sind Sie sicher, dass die Methode, die Sie schreiben, nur mit Klasse B funktioniert, sollten Sie eine neue Methode in Klasse B schreiben.
quelle
Verwenden Sie überladene Funktionen. Benötigt keine Unterstützung für dynamic_cast oder RTTI:
quelle
Wenn Sie auf die Boost-Bibliothek zugreifen können , benötigen Sie möglicherweise die Funktion type_id_with_cvr () , die den Datentyp bereitstellen kann , ohne die Modifikatoren const, volatile und &&& zu entfernen . Hier ist ein einfaches Beispiel in C ++ 11:
Hoffe das ist nützlich.
quelle