Abstrakte Funktionen



  • Bin in meinem Buch gerade bei abstrakten Funktionen. Und da heißt es ja, das wenn man eine abstrakte Funktion in der Basisklasse hat, dann MUSS man diese in der abgeleiteten Klasse redefinieren, oder die abgeleitete Klasse ist auch eine Abstrakte Klasse. Aber jetzt mal hier n Beispiel:

    class Start
    {
        public:
        virtual void func() = 0;
    }
    
    class A : public Start
    {
        public:
        void func() const; // ah ZACK wird nicht redefiniert wegen dem const
    }
    
    class B : public A
    {
       public:
       void temp(); // ohne const!
    }
    

    Was passiert jetzt mit "B"? Weil wenn "A" doch abstrakt ist, dann müsste doch die abgeleitete Klasse "B" auch abstrakt sein? Und das könnte ich ja gar nicht mehr verhindern, weil mmhhh...umso länger ich drüber nachdenke desto verrückter wirds, in A müsste ja dann eigentlich eine abstrakte Funktion stecken...die in "B" redefiniert wird....aber dann müsste "A" ja schon von anfang an abstrakt sein....und wenn man nun doch die Funktion von "Start" in a redefinieren würde...dann dürfte A gar nicht mehr abstrakt sein müsste es aber doch weil ja eine abstrakte Funktion drin vorkommt. Umso länger ich drüber nachdenke, umso mehr werde ich verrückt im Kopf... 😮 😕
    Also die Frage steht noch: Was passiert mit Klasse "B"?
    Und noch eine Frage, was würde passieren wenn man in "B" jetzt "func()" redefiniert, nix? Also ich mein wenn in B jetzt halt stehen würde, "void func()"...würde dann nix passieren? Gibts da irgendwie keinen Zugriff mehr...?

    Und was würde den nun in diesem Fall passieren:

    class start
    {
         public:
         virtual void func() = 0;
    }
    
    class A : public start
    {
         public:
         virtual void func() = 0; //Geht das überhaupt????
         void blop() = 0;
    }
    
    class B : public A
    {
        public:
        void blop();
    }
    
    class C : public A
    {
        public:
        void func();
        void blop();
    }
    

    Welche Klasse ist abstrakt...welche nicht?

    Also mit den Zugriffsregeln in unterschiedliche Klassen + Vererbung....da komm ich manchmal schon in Denkschleifen irgendwie...da wird mir ganz heiß :D. Mir kommts so vor als gibts da soviele Möglichkeiten etc...na ja.

    MfG
    Stromberg


  • Mod

    Stromberg schrieb:

    Bin in meinem Buch gerade bei abstrakten Funktionen. Und da heißt es ja, das wenn man eine abstrakte Funktion in der Basisklasse hat, dann MUSS man diese in der abgeleiteten Klasse redefinieren, oder die abgeleitete Klasse ist auch eine Abstrakte Klasse. Aber jetzt mal hier n Beispiel:

    class Start
    {
        public:
        virtual void func() = 0;
    }
    
    class A : public Start
    {
        public:
        void func() const; // ah ZACK wird nicht redefiniert wegen dem const
    }
    
    class B : public A
    {
       public:
       void temp(); // ohne const!
    }
    

    Was passiert jetzt mit "B"? Weil wenn "A" doch abstrakt ist, dann müsste doch die abgeleitete Klasse "B" auch abstrakt sein? Und das könnte ich ja gar nicht mehr verhindern, weil mmhhh...umso länger ich drüber nachdenke desto verrückter wirds, in A müsste ja dann eigentlich eine abstrakte Funktion stecken...die in "B" redefiniert wird....aber dann müsste "A" ja schon von anfang an abstrakt sein....und wenn man nun doch die Funktion von "Start" in a redefinieren würde...dann dürfte A gar nicht mehr abstrakt sein müsste es aber doch weil ja eine abstrakte Funktion drin vorkommt. Umso länger ich drüber nachdenke, umso mehr werde ich verrückt im Kopf... 😮 😕
    Also die Frage steht noch: Was passiert mit Klasse "B"?

    Start ist abstrakt, denn hier wird die rein-virtuelle Funktion void func() deklariert. A ist abstrakt, denn die von Start geerbte Funktion func wird hier nicht überschrieben. Auch B ist aus dem gleichen Grund abstrakt.

    Und noch eine Frage, was würde passieren wenn man in "B" jetzt "func()" redefiniert, nix? Also ich mein wenn in B jetzt halt stehen würde, "void func()"...würde dann nix passieren? Gibts da irgendwie keinen Zugriff mehr...?

    Wenn in B eine nicht-statische Funktion void func() deklartiert wird, so überschreibt diese die aus A geerbte rein-virtuelle Funktion func. Sofern diese in B deklarierte Funktion nicht rein-virtuell ist, ist B dann nicht abstrakt.

    Und was würde den nun in diesem Fall passieren:

    class start
    {
         public:
         virtual void func() = 0;
    }
    
    class A : public start
    {
         public:
         virtual void func() = 0; //Geht das überhaupt????
         void blop() = 0;
    }
    
    class B : public A
    {
        public:
        void blop();
    }
    
    class C : public A
    {
        public:
        void func();
        void blop();
    }
    

    Welche Klasse ist abstrakt...welche nicht?

    Alle, mit Ausnahme von C.

    Also mit den Zugriffsregeln in unterschiedliche Klassen + Vererbung....da komm ich manchmal schon in Denkschleifen irgendwie...da wird mir ganz heiß :D. Mir kommts so vor als gibts da soviele Möglichkeiten etc...na ja.

    Zugriffsbeschränkungen spielen beim Überschreiben virtueller Funktionen keine Rolle - es findet ja auch gar kein Zugriff statt (natürlich spielen solche Beschränkungen ggf. bei der Definition einer Funktion eine Rolle) 😉



  • Hallo,

    erstmals fehlen hinter all Deinen Klassendeklarationen ';'.

    Weil wenn "A" doch abstrakt ist, dann müsste doch die abgeleitete Klasse "B" auch abstrakt sein?

    Ja, ist sie, weil Du die rein virtuelle Methode nicht in B definierst.

    Und das könnte ich ja gar nicht mehr verhindern, weil mmhhh...umso länger ich drüber nachdenke desto verrückter wirds

    Doch kannst Du verhindern (s. auch o.):

    class B : public A 
    { 
       public: 
       void temp(); // ohne const! 
       void func() {}
    };
    

    in A müsste ja dann eigentlich eine abstrakte Funktion stecken...die in "B" redefiniert wird....

    Ja, tut sie auch: func()

    aber dann müsste "A" ja schon von anfang an abstrakt sein....

    A ist abstrakt, da func() dort nicht redefiniert wird.

    und wenn man nun doch die Funktion von "Start" in a redefinieren würde

    Dann wäre A nicht mehr abstrakt...

    müsste es aber doch weil ja eine abstrakte Funktion drin vorkommt

    Wenn Du func() redefinierst, kommt da nichts mehr abstraktes (eigentlich: rein virtuelles) vor!

    Was passiert mit Klasse "B"?

    So wie es in Deinem Bsp. ist, ist B abstrakt.

    Und noch eine Frage, was würde passieren wenn man in "B" jetzt "func()" redefiniert, nix?

    s.o. => nicht mehr abstrakt

    Zum 2. Bsp.:

    void blop() = 0;
    

    Das ist schmu. Du meinst wohl

    virtual void blop() = 0;
    

    Welche Klasse ist abstrakt...welche nicht?

    start, A und B abstrakt.

    C kann instanziiert werden.

    - start abstrakt, da func() rein virtuell
    - A abstrakt, da func() und blob() rein virtuell
    - B abstrakt, da func() nicht redefiniert => immer noch rein virtuell
    - C instanzierbar, da blob() und func() redefiniert

    [cpp]virtual void func() = 0; //Geht das überhaupt???? [/codecpp
    Ja, aber hier sinnfrei. Es ändert an nichts an der Konstruktion.



  • Wenn ich das richtig verstanden habe, ist auch die abgeleitetet Klasse von der abgeleitetet Klasse abstrakt....wenn der ihre Basisklasse auch abstrakt war..(mh komischer Satz).
    Folgendes Beispiel:

    class start
    {
        public:
        virtual void func() const = 0;
    };
    
    class A : public start
    {
        public:
        virtual void func();
    };
    
    class B : public A
    {
        public:
        virtual void func();
    };
    
    class C : public B
    {
        public:
        void func() const;
    };
    
    class D : public C
    {
        public:
        void blop();
    };
    

    Nach Meiner Logik ist jetzt "start", "A" und "B" abstrakt, man kann sie also nicht einzeln deklarieren! Und "C" und "D" sind nicht abstrakt?

    MfG
    Stromberg

    EDIT: Mh...kp warum ich überall die ";" am Klassenende vergessen habe...strange 😃



  • Nur start ist abstrakt.



  • da hast du wohl übersehen, dass void func () const und void func() zwei unterschiedliche methoden sind.



  • Häää? Nur "start" ist abstrakt? Das verstehe ich jetzt wieder nicht.



  • Ups, das const habe ich übersehen. Dann ist start, A und B abstrakt.



  • Stromberg schrieb:

    Häää? Nur "start" ist abstrakt? Das verstehe ich jetzt wieder nicht.

    start, A und B sind abstrakt. aber nur, weil du in A und B eine andere funktion als "void func () const" deklariert hast (nämlich "void func ()").


Anmelden zum Antworten