Typenvariable Argumente, aber Boost.Any schlechter Stil?
-
Decimad schrieb:
Macht es denn bei so einer Form von Downcast einen Unterschied, ob ich reinterpret_cast oder static_cast verwende?
Ich weiß jetzt nicht genau, was für einen Cast du meinst. Aber wenn du dich innerhalb einer Vererbungshierarchie bewegst, solltest du entweder dynamic_cast oder static_cast verwenden. Bei reinterpret_cast findet ein ggf notwendiges Adjustment nicht statt. Das knallt dir dann spätestens bei Mehrfachvererbung um die Ohren, siehe hier.
#include <iostream> using namespace std; struct A {int i;}; struct B {int j;}; struct C : A, B {}; int main() { C c; B& b = c; C& c2 = static_cast<C&>(b); C& c3 = reinterpret_cast<C&>(b); cout << &c << endl; cout << &b << endl; cout << &c2 << endl; cout << &c3 << endl; }Bei meinem Test sieht man, dass die Adressen &c und &b unterschiedlich sind. Der static_cast für c2 ist quasi die Umkehrung dieser impliziten Wandlung und stellt die richtige Adresse wieder her. Der reinterpret_cast führt hier dazu, dass c3 keine gültige Referenz auf ein C-Objekt ist.
-
Okay, danke Dir für die ausführliche Erklärung!
Ich find Mehrfachvererbung sowieso blöd, das führt immer zu Streitereien!
Hast Du auch eine Ahnung wie das mit dem Löschen bei Mehrfachvererbung läuft, wie ich im zweiten Edit fragte?
-
Decimad schrieb:
Edit2: Herrje, wie funktioniert in solch einem Fall eigentlich das delete? Okay, die Zerstörung geht dank virtuellem Destruktor ja problemlos, aber wie bekommt delete die Richtige Basisadresse raus? Gibt's da eine versteckte virtuelle Funktion, die die Basisadresse der konkreten Klasse ausspuckt?
Naja, dass es für die Implementierung kein Problem sein kann/darf, die "Basisadresse" zu ermitteln, sollte ja wohl klar sein.
Der VTable-Zeiger eines z.B. Foo-Teilobjekts das Teil eines Bars ist zeigt (bei Mehrfachverrebung) ja nicht auf den Foo-VTable oder Bar-VTable, sondern auf einen speziellen Foo-in-Bar-VTable.
Da der VTable nicht nur die Adressen von virtuellen Funktionen enthält, sondern auch einen Zeiger auf Informationen über das Layout des konkreten Objekts, kann man da einiges machen.
Ist auch nötig, sonst könntedynamic_castnicht implementiert werden.Und um deine konkrete Frage auch noch zu beantworten: ja, es gibt so eine Funktion, und zwar
dynamic_cast<void*>(p)(wobei das nicht unbedingt eine versteckte virtuelle Funktion ist, aber es werden sicher Informationen aus dem VTable oder darin verlinkten Datenstrukturen verwendet). Das liefert die Adresse des "most derived object" -- also die Anfangsadresse des konkreten Objekts.
Das wird auch die Adresse sein die üblicherweise anoperator deleteübergeben wird. Bzw. ich meine sogar dass es immer die Adresse sein muss die anoperator deleteübergeben wird, ich glaube nicht dass der Standard hier genug Spielraum lässt es anders zu implementieren.