B erbt A, C erbt A, D erbt B UND C



  • Hallo 🤡

    class A ...
    class B : public A ...
    class C : public A ...
    
    class D : public B, public C ...
    

    Geht ja bekanntlich nicht.
    Aber kann man das nicht so hinbiegen dass B und C auf "ein gemeinsames A" zurückgreifen - wenn ihr verseht 🙄

    Geht das nicht IRGENDWIE? Damit wären nette Sachen möglich 😃



  • ja. beim erben virtual dazuschreiben.



  • Ty 4 reply

    volkard schrieb:

    ja. beim erben virtual dazuschreiben.

    😕 Wie genau meinst du das?



  • so



  • Ganz ausgezeichnet.
    Danke 😋



  • #include <iostream>
    using namespace std;
    
    class Base {};
    
    class A : virtual Base {};
    
    class B : virtual Base {};
    
    class Deri : public A, public B {};
    
    int main()
    {
        Base* d = new Deri();
    }
    

    😮 😮

    test.cpp: In function »int main()«:
    test.cpp:14: Fehler: »Base« ist eine nicht erreichbare Basis von »Deri«

    Bitte sagt mir dass ich die Deri Instanzen zu einem Base* casten kann! 😮



  • virtual ist gut, aber noch lange kein grund, public wegzumachen.



  • volkard schrieb:

    virtual ist gut, aber noch lange kein grund, public wegzumachen.

    Haha ja stimmt 🙄

    Ich wollte mit dem Beispiel einen Bug reproduzieren aber das hat mir Mr. Leichtsinn versaut 😉

    Ich bekomme folgenden Fehler:

    src/core/allo.h: In member function »BASE* allocator_t<BASE, DERIVED, SIZE>::alloc(const BASE*) [with BASE = faceGraph_t, DERIVED = graph3DLab_t, int SIZE = 1]«:
    src/main.cpp:117: instantiated from here
    ../../../../SAK3D/src/core/allo.h:46: Fehler: Es kann nicht von Basis »graph_t« in abgeleiteten Typ »lab_t« über virtuelle Basis »faceGraph_t« gewandelt werden
    make: *** [build/obj/main.o] Fehler 1

    Ich poste gleich den code ... aber vielleicht sagt ja die Fehlermeldung schon etwas mehr als mi? 😕

    Ty



  • Ich habe Fortschritte gemacht.
    Alles lässt sich auf dieses Problem reduzieren:

    #include <iostream>
    using namespace std;
    
    class Base {};
    
    class A : virtual public Base {};
    
    class B : virtual public Base {};
    
    class Deri : public A, public B {};
    
    int main()
    {
        Base* d = new Deri();
    
        Deri* test = (Deri*)d;
    }
    

    Ein Up-cast geht doch beim klassischen erben auch!

    [quote]bug.cpp: In function »int main()«:
    bug.cpp:16: Fehler: Es kann nicht von Basis »Base« in abgeleiteten Typ »Deri« über virtuelle Basis »Base« gewandelt werden[cpp]



  • schätze, das geht nicht mehr so einfach.

    class Base {
        public:
        virtual ~Base(){}
    };
    
    class A : virtual public Base {};
    
    class B : virtual public Base {};
    
    class Deri : public A, public B {};
    
    int main()
    {
        Base* d = new Deri();
    
        Deri* test = dynamic_cast<Deri*>(d);
    }
    


  • derivate schrieb:

    Ein Up-cast geht doch beim klassischen erben auch!

    du meinst downcast. die wurzel ist oben.


  • Administrator

    Zwei Probleme:
    1. Der C Cast reicht hier definitiv nicht mehr aus. Ein dynamic_cast muss her. Auf C Cast sollte man beim polymorphen Casten sowieso verzichten. Grundsätzlich ist der Verzicht in C++ auf C Cast allgemein von Vorteil.
    2. Um so ein Down-Cast machen zu können, brauchst du eine vTable. Die ist aber nicht vorhanden, weil du keine virtuelle Funktionen hast. Mach am einfachsten einen virtuellen public Destruktor in die Baseklasse rein.

    Grüssli



  • Ihr seid großartig! Danke 🕶

    Sollte man bei jedem dynamic_cast prüfen ob er erfolgreich war??

    if(dynamic_cast<Deri*>(d)) cout << "supi" << endl; else cout << "!supi" << endl;
    


  • derivate schrieb:

    Ihr seid großartig! Danke 🕶

    Sollte man bei jedem dynamic_cast prüfen ob er erfolgreich war??

    if(dynamic_cast<Deri*>(d)) cout << "supi" << endl; else cout << "!supi" << endl;
    

    wenn die daten funktionsargumente sind, eher schon. könnte ja jeder kommen, und dir mist schicken.
    wenn du selber die daten gebastelt hast und sicher bist, daß nicht 0 rauskommen kann, kannste den test auch lassen.


Anmelden zum Antworten