static_cast<> für upcast?
-
sowas ähnliches dachte ich mir bereits

in meinem fall ist aber der vollständige typ von
derived
bekannt.struct Interface { virtual void func() = 0; }; struct SpecialInterface : virtual public Interface { virtual void foo() = 0; }; ///////////////////////////////////////////////////////// class Impl : virtual public Interface { public: void func(); // nicht abstrakt, implementationsklasse }; class SpecialImpl : virtual public SpecialInterface, public Impl { public: void foo(); }; void do_something(SpecialInterface *ptr) { // hier ist der vollständige typ von SpecialImpl bekannt. // ptr ist zu 100% ein SpecialImpl! SpecialImpl *impl = static_cast<SpecialImpl *>(ptr); // erlaubt? } int main() { SpecialInterface *ptr = new SpecialImpl; do_something(ptr); delete ptr; }in diesem A B C D diagramm (b und c erben von a, d von b und c)
möchte ich nicht von A nach D, sondern von B nach D.
alle typen sind vollstädnig bekannt.afaik muss
static_castevtl beim cast von D nach B den this-pointer
verändern, je nachdem wo B liegt. dieser offset muss compiletime-konstant
sein, da die klassen sich nicht ändern.jetzt möchte ich nur den umgekehrten weg gehen. B -> D. B ist ein D.
natürlich könnte man den voodoo-hack nehmen (:D) und einfach den offset abziehen,
aber kannstatic_castdas nicht auch?
-
warum benutzt du hier die virtuelle Vererbung? Das Ding kommt eigentlich nie(!) vor. Außer natürlich, du hast ein schlechtes Design (wie zum Beispiel nen kombinierten input/outputstream *hust*)
-
cast-spaß schrieb:
afaik muss
static_castevtl beim cast von D nach B den this-pointer
verändern, je nachdem wo B liegt. dieser offset muss compiletime-konstant
sein, da die klassen sich nicht ändern.jetzt möchte ich nur den umgekehrten weg gehen. B -> D. B ist ein D.
natürlich könnte man den voodoo-hack nehmen (:D) und einfach den offset abziehen,
aber kannstatic_castdas nicht auch?Niemand teilt static_cast den vollständigen Typ mit, also nein. Die einzige Möglichkeit, die mir auf Anhieb einfällt, ist das Offset explizit in den Quellcode zu schreiben und dann bei der Ausführung zu testen, ob der Wert stimmt, oder ggf. beim Konfigurieren des Projekts ein kleines Script auszuführen, dass diesen Wert ermittelt und diesen beim Compilieren weiterzugeben.
Warum hier virtuelle Vererbung zwischen SpecialInterface und SpecialImpl benutzt wird, erschließt sich mir ebensowenig wie otze.
-
weil ich damit erzwinge, dass die konkrete funktion die abstrakte überschreibt,
und nicht anderherum. habe ich vor langer zeit herausgefunden, und seitdem
immer für interfaces genommen.ich möchte auch wirklich nur ein objekt der basisklasse.
-
Ahh ich sehs grad...dein Design ist wahrscheinlich ziemlich wirr...
Das Poblem ist, dass du SpecialImpl von Impl erben lässt...das ist meistens nicht gut.
-
warum sollte das nicht gut sein?
ich vermeide so das erneute definieren von jeweils 5 funktionen in ~70 klassen.
das bringt schon etwas.
-
cast-spaß schrieb:
ich vermeide so das erneute definieren von jeweils 5 funktionen in ~70 klassen.
das bringt schon etwas.Wär das nicht ein Fall von: das gehört ins Interface, weil es eh in allen Klassen gleich ist?
C++ ist nicht Java.
-
otze schrieb:
cast-spaß schrieb:
ich vermeide so das erneute definieren von jeweils 5 funktionen in ~70 klassen.
das bringt schon etwas.Wär das nicht ein Fall von: das gehört ins Interface, weil es eh in allen Klassen gleich ist?
C++ ist nicht Java.
java *igitt*
Ist ja auch alles im Interface, aber die vererbungshierachie der Interfaces
möchte ich auch in der klassenstruktur nachbilden. d.h.klassen | interface | CA <-|- A | | | v | v CB <-|- B | | | v | v CC <-|- CA, B und C sind die interfaces. ich kenne genug libarys, deren öffendliche
schnittstelle auf vererbung basiert.die einzige gute möglichkeit ist halt die mehrfachvererbung.
ich hatte es auch schon mal mit class-chaining versucht, via templates.
aber das war eine katastrophe, sprich _nicht_ schön.
-
ich bins nochmal

// öffentliches interface struct Base { virtual void func() = 0; }; struct Interface : virtual public Base //// <-- ES GEHT UM DAS VIRTUAL HIER { virtual void specialfunc() = 0; }; //////////// ab hier die implemenatation class CBase : virtual public Base { void func(){} }; class CInterface : virtual public Interface, public CBase { void specialfunc(){} }; int main() { CInterface *ptr = new CInterface; Interface *iptr = ptr; Base *b = iptr; Interface *iptr2 = static_cast<Interface *>(b); // geht nicht :( }mit dem virtual kann er nicht von
Base *zuInterface *
koonvertieren, ohne virtual überschreibt meine funktion das interface
nicht, und die funktion ist immer noch abstrakt.wie kann ich das umgehen? ab besten ohne solche haXXs, das muss doch gehen.
ohne dynmaic_cast
MfG cast-spaß
-
Nein, virtual macht dir alles kaputt.
-
Warum willst du eigentlich keinen dynamic_cast verwenden?
-
es ist zu langsam.
grade die msvc-implementierung ist eine katastrophe. irgentwo meine ich
gelesen zu haben, dass die funktion klasseninfos aus der .exe liest.meine jetzige lösung ist eine virtuelle methode in dem interface, void *Downcast()
der teil ist wirklich performancekritisch und wird tausende male aufgerufen