Funktionskörper für abstrakte Funktion in Basisklasse



  • Ne, es is eben nicht logisch.

    Dein c erbt von a und von b (somit noch einmal von a), hat also somit 2mal von
    a geerbt. Einmal wird die pure virtual Funktion auch überschrieben, nur eben
    das zweite Mal nicht.

    Mit virtuellen Basisklassen klappts, wobei ich mir vllt trotzdem irgendwie
    das Design nochmal durchdenken würde.

    class Base {
    public:
    	virtual void mf() = 0;
    };
    
    class Derived : virtual public Base {
    public:
    	virtual void mf();
    };
    
    class MoreDerived : virtual public Base, public Derived {
    
    };
    


  • class a{
    public:
      virtual void x()=0;
    };
    class a: public a{
    public:
      virtual void y()=0;
    };
    

    interessant... 🤡



  • Oh, da sollte a2 hin 😉

    Danke, das klappt.
    Aber warum kann man keinen static_cast von einer Basisklasse zu C machen, aber einen dynamic_cast?



  • static_cast geht, nur kratzt dir das prorgamm ab,wenn die basisklasse nicht wirklich c ist.



  • Wie geht denn das beim static_cast, das funktioniert nämlich nicht:

    c dd;
      a* d2=ⅆ
      c* d3;
      d3=dynamic_cast<c*>(d2);    // ok
      d3=static_cast<c*>(d2);     // Compilerfehler: invalid static_cast from type `a*' to type 
      d3=(c*)(d2);                // Compilerfehler: cannot convert from base `a' to derived type `c' via virtual base 
    `c*'
    

    @Tankian: Was sollte icb den beim Klassendesign verändern?



  • @Tankian: Was sollte icb den beim Klassendesign verändern?

    Mehrfachvererbung vermeiden ..

    Zum Beispiel könntest du deine gesamten Impl-Klassen
    mit Layering implementieren.

    class ImplButton : public ImplControl {
    public:
        ImplButton()
        {
        }
    
        virtual void onClick()
        {
            // ...
        }
    };
    
    class Button : public Control {
    public:
        Button() : impl(new ImplButton)
        {   // normalerweise würd ich sowas mit auto_ptr machen ..
        }
    
        ~Button()
        {
            delete impl;
        }
    
        virtual void onClick()
        {
            impl->onClick();
        }      
    
    private:
        ImplButton* impl;
    };
    

    In dem Beispiel hier is es grad auch dasselbe wie das pimpl-Idiom.

    Tankian



  • BeniBela schrieb:

    Zum btw:
    Mit virtual find ich es eigentlich klarer.

    War auch nur ein Vorschlag, ist ja schliesslich nicht falsch, es nochmals hinzuschreiben.

    BeniBela schrieb:

    d3=dynamic_cast<c*>(d2);    // ok
      d3=static_cast<c*>(d2);     // Compilerfehler: invalid static_cast from type `a*' to type
    

    Also bei mir funktioniert static_cast problemlos. Probier das mal mit einem Minimalbeispiel. Wenn's dann funktioniert, muss das Problem woanders liegen.
    Übrigens, welchen Compiler hast du?

    @Tankian
    Events so zu handeln find ich recht unpraktisch. Funktionsadapter scheinen mir da passender zu sein. Wenn ich das richtig sehe, musst du für alle Controls eine eigene Klassenimplementation schreiben oder seh ich das falsch.
    Da ich momentan für einen Optionsdialog eines Plugins an einem kleinen GUI arbeite, welches die WinAPI kapselt, hab ich mir darüber auch schon einige Gedanken gemacht. Und da finde ich die Vorgehensweise, wie es zB auch bei C++/CLI gemacht wird, praktischer.



  • Bei einem Minimalprogramm kommt das gleiche :(:

    #include <iostream>
    class a{
    public:
      virtual void x()=0;
    };
    class b:virtual public a{
    public:
      virtual void x();
    };
    void b::x(){std::cout << "b::x";}
    
    class c: virtual public  a ,public b {
    public:
    };
    
    int main(int argc, char *argv[])
    {
      c dd;
      a* d2=&dd;
      c* d3;
      d3=dynamic_cast<c*>(d2);
      d3->x();               //wenn die statischen weggelassen werden, wird b::x aufgerufen.
      d3=(c*)(d2);
      d3=static_cast<c*>(d2);
    
      system("PAUSE");	
      return 0;
    }
    
    make.exe -f "E:\temp\delete\temp\Makefile.win" all
    g++.exe -c main.cpp -o main.o -I"D:/MinGW/include"  -I"D:/MinGW/include/c++"  -I"D:/MinGW/include/sys"  -I"D:/MinGW/include/c++/3.2.3"  -I"D:/MinGW/include/c++/3.2.3/mingw32"  -I"E:/c++komps/simpleUtils"  -I"D:/MinGW/include/dx"  -I"D:/ddks/Microsoft Platform SDK/Include"    -fexpensive-optimizations
    
    main.cpp: In function `int main(int, char**)':
    
    main.cpp:24: cannot convert from base `a' to derived type `c' via virtual base 
       `a'
    main.cpp:25: invalid static_cast from type `a*' to type `c*'
    make.exe: *** [main.o] Error 1
    

    Der Coompiler ist MingW mit Gcc 3.2.3.

    zum Design:
    @Tankian:
    Dann muss aber Button die Klasse ImplButton kennen, das wollte ich gerade vermeiden.
    @groovemaster:
    Was hat denn C++/CLI mit GUI zu tun? Ist das nicht der Nachfolger von Managed C++?



  • groovemaster:

    Natürlich würd ich das mit den Events selbst auch nicht so lösen, ich hab nur
    blind drauf los irgendeinen Methodennamen gewählt, der halbwegs zu Control passt.
    Normalerweise würd ich da mit boost::signal arbeiten.

    BeniBela:

    Google mal selbst nach dem pimpl-Idiom.
    Mein Beispiel sollte nur Layering zeigen, den
    Rest darfst dir selbst ergooglen.

    Tankian



  • @BeniBela
    Ich vermute mal, dass die virtuelle Vererbung deinen Compiler streiken lässt. Da das keine einfache Thematik ist, solltest du dir mal anschauen, was der Standard dazu sagt. Vielleicht ist aber auch Hume so gnädig und klärt dich (uns 🙂 ) auf. Wobei ich mir momentan nicht sicher bin, warum und ob überhaupt virtuelle Vererbung bei dir notwendig ist.

    BeniBela schrieb:

    Was hat denn C++/CLI mit GUI zu tun?

    C++/CLI ist die MS Antwort für das Designen von GUIs (Forms) unter C++. Zumindest in der aktuellen Ausgabe des Visual Studios. Wie du schon richtig gesagt hast, war Managed C++ mehr oder weniger der Vorgänger.



  • Na super, der Standard verbietet es 😞
    Dann werd ich es wohl mal mit dem Pimpl-Idiom versuchen, und mir C++/CLI angesehen.

    Danke für die Antworten.


Anmelden zum Antworten