Klassen in C++ Durchschnitt von zwei Zahlen berechnen



  • Ich habe nun meine Klasse mit einer Abgeleiteten Klasse erweitert. Die sollte das Ergebniss von Average übernehmen und es quadrieren. Nur kommt bei mir nun der Fehler dass _avg private ist. Kann ich den Wert nicht einfach in der abgeleiteten Klasse übernehmen?

    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    
    using namespace std;
    
    
    class Average{
    
    private:
        double _avg=0;
        double _sum=0;
        int _count=0;
    
    public:
        void add(double val){
                 _sum += val; // sum =sum + val
                 _count++;
                 _avg = _sum / _count;
        }
    
        double get_avg(){return _avg;}
    
    };
    
    
    class Abgeleitet : public Average{
    
        private: double _qdr=0;
    
        public:
            void quadrieren(double get_avg()){
                 _qdr= _avg * _avg;
        }
    
        double get_qdr(){return _qdr;}
    
    
    
        };
    
    int main(){
    
        Average a;  // Standardkonstruktor
        Abgeleitet b;
    
        a.add(12.4);
        a.add(23.7);
    
    
        cout << a.get_avg() << endl;
        cout << b.get_qdr() << endl;
    
    
        return 0;
    
    }
    
    

  • Mod

    @jasmin89 sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Kann ich den Wert nicht einfach in der abgeleiteten Klasse übernehmen?

    Genau das sagt private aus. Das ist auch gut so, denn welchen Grund hast du an den Innereien deiner Elternklasse herumzuspielen? Sie bietet doch sogar kontrollierten Zugriff auf den Durchschnitt als Teil ihrer öffentlichen Schnittstelle an. Benutz den!

    Wenn es Ziel ist, dich mit Klassen näher zu beschäftigen, dann sind die Zugriffsspezifizierer ein wichtiges Thema.



  • @jasmin89 sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    public:
    void quadrieren(double get_avg()){
    _qdr= _avg * _avg;
    }

    Kannst du erklären, was du hier vor hast: void quadrieren(double get_avg())? Mir geht es insbesondere um den Teil in der Klammer.



  • @SeppJ: Danke. Ich habe mir ja die Memberfunktion get_avg() definiert um diese Schnittstelle nach außen von _avg zu haben. Ich kann diese auch in der Konsole ausgeben. Aber wie kann ich das Ergebnis der Funktion get_avg() auch in der abgeleiteten Klasse verwenden? Müsste ich nicht Zugriff auf das Ergebnis von get_avg() in der Abgeleiteten Klasse haben? Denn ich bekomme es nicht hin genau dieses Ergebnis in der Klasse Abgeleitet zu verwenden.



  • @jasmin89 sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Müsste ich nicht Zugriff auf das Ergebnis von get_avg() in der Abgeleiteten Klasse haben?

    Du hast in der abgeleiteten Funktion Zugriff auf die Funktion get_avg(). Was meinst du mit dem Zusatz "das Ergebnis von"?

    Ich finde es allerdings etwas fragwürdig, dass die den Durchschnitt als Membervariable hast (und das nun auch mit dem Quadrat versuchst). Du müsstest dann das add überschreiben, um auch das Quadrat zu aktualisieren. Besser wäre vermutlich, wenn du den Durschnitt immer on-the-fly berechnest. Dann kannst du auch das Quadrat immer on-the-fly berechnen.

    Ich frage mich aber auch, wozu du hier überhaupt eine Klassenhierachie brachst.



  • @jasmin89 3 Sachen stimmen meiner Meinung nach noch nicht.

    1. Statt private musst du protected, in der Klasse Average, verwenden, damit die Kindklasse die Variablen und Funktionen sieht und sie dennoch außerhalb deiner Klasse unsichtbar sind.
    2. Du kannst der Funktion quadrieren() nicht get_avg() übergeben und hoffen dass der Wert da schon irgendwie rauspurzelt. Du kannst jedoch in quadieren() get_avg() aufrufen.
    3. In der main() hast du 2 verschiedene Objekte a und b. Wenn du a Werte zuweist, hat b trotzdem noch keine Werte erhalten. Genauso wäre es ja auch mit 2 Objekten der selben Klasse.
    #include <stdio.h>
    #include <stdlib.h>
    #include <iostream>
    
    using namespace std;
    
    class Average{
    
    protected:
        double _avg=0;
        double _sum=0;
        int _count=0;
    
    public:
        void add(double val){
                 _sum += val; // sum =sum + val
                 _count++;
                 _avg = _sum / _count;
        }
    
        double get_avg(){return _avg;}
    };
    
    class Abgeleitet : public Average{
    
        private: double _qdr=0;
    
        public:
            void quadrieren(){
                 a = get_avg();
                 _qdr= a * a;
        }
    
        double get_qdr(){return _qdr;}
        };
    
    int main(){
    
        Average a;  // Standardkonstruktor
        a.add(12.4);
        a.add(23.7);
        cout << a.get_avg() << endl;
    
        Abgeleitet b;
        b.add(12.4);
        b.add(23.7);
        cout << b.get_qdr() << endl;
    
        return 0;
    }
    

    Für den Code übernehme ich keine Garantie, den hab ich live in den Browser getippt.



  • @shokwave sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Statt private musst du protected, in der Klasse Average, verwenden, damit die Kindklasse die Variablen und Funktionen sieht und sie dennoch außerhalb deiner Klasse unsichtbar sind.

    Und warum genau soll die abgeleitete Klasse die member Variablen von Average kennen? Genau dafür gibt es doch den Getter.



  • @Schlangenmensch sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Und warum genau soll die abgeleitete Klasse die member Variablen von Average kennen? Genau dafür gibt es doch den Getter.

    Du hast natürlich Recht, die braucht man, wenn man den Getter benutzt nicht mehr. Da hätte ich besser schreiben sollen entweder get_avg() benutzen oder die Variablen protected machen.

    Ich hab den Code nochmal überarbeitet, weil er so nicht lauffähig war.

    #include <iostream>
    
    using namespace std;
    
    class Average {
    
    private:
        double _sum=0;
        int _count=0;
    
    public:
        void add(double val) {
             _sum += val; // sum = sum + val
             _count++;
        }
    
        double get_avg() {
    		return _sum / _count;
    	}
    };
    
    class Abgeleitet : public Average{
    
    public:
        double get_qdr() {
             double a = get_avg();
             return a * a;
    	}
    };
    
    int main() {
    
        Average a;  // Standardkonstruktor
        a.add(18.7);
        a.add(19.6);
        cout << "Average von a = " << a.get_avg() << endl;
    
        Abgeleitet b;
        b.add(12.4);
        b.add(23.7);
        cout << "Average von b = " << b.get_avg() << endl;
        cout << "Quadrat von b = " << b.get_qdr() << endl;
    
        return 0;
    }
    

  • Mod

    @shokwave sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Da hätte ich besser schreiben sollen entweder get_avg() benutzen oder die Variablen protected machen.

    Nein, bitte gar nicht protected benutzen hier! Dies wäre das perfekte Beispiel wenn ich irgendwann mal einen Artikel "Protected considered harmful" schreiben sollte.

    Wenn man protected nutzt, koppelt man diese Teile der Implementierung der Elternklasse fest an die Kinderklassen. Das will man im Allgemeinen¹ nicht! Dann sind diese Teil der öffentlichen(! Denn jeder kann von uns erben!) Schnittstelle der Klasse und müssen entsprechend respektiert werden. In diesem Falle hieße das, dass Average stets dafür zu sorgen hätte, dass der Wert in _avg aktuell und konsistent ist. Man kann also niemals von der hier anfangs vorgeschlagenen Implementierung weg (oder muss sie stets zusätzlich mit herumschleppen), obwohl eine der ersten Reaktionen auf diese Implementierung direkt war, dass es eigentlich gar keinen Sinn macht, diesen Zwischenwert ständig neu abzuspeichern, sondern man den Wert besser nur bei Bedarf in get_avg berechnen könnte. Wie du es ja auch selber vormachst.

    Jedenfalls sollte man niemals Implementierungsdetails einer Klasse zum Teil der öffentlichen Schnittstelle machen, und protected ist Teil der öffentlichen Schnittstelle.

    ¹: Irgendwo gab's hier im Forum schon einmal eine Diskussion, wann man es doch wollen könnte. Aber sagen wir es so: Wenn es gerechtfertigt ist, dann weiß man es auch, weil man gute Designgründe hat. "Ich möchte aber darauf zugreifen können!" ist kein guter Grund.



  • @SeppJ Danke für die Klarstellung. So hatte ich das noch nicht gesehen, aber es macht natürlich alles Sinn was du schreibst.



  • @SeppJ sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Wenn man protected nutzt, koppelt man diese Teile der Implementierung der Elternklasse fest an die Kinderklassen.

    Das tut man in C++ immer, da jede Änderung der Elternklasse die ABI bricht, vollkommen unabhängig davon ob man Getter oder protected nutzt. Getter haben in C++ geringere Vorteile, in anderen Sprachen sieht die Sache anders aus, da bekommt man eine komplette Entkopplung mit dem Verzicht auf protected.

    In Kurzform für C++: Es gibt eine Entkopplung in der API aber weiterhin Abhängigkeit in der ABI beim Verzicht auf protected.


  • Mod

    Und ABIs interessieren bei Designfragen inwiefern? Typischer Beitrag von dir, völlig nutzlos, nur um irgendwas vermeintlich klug klingendes zu sagen.



  • @SeppJ sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Und ABIs interessieren bei Designfragen inwiefern?

    Kommt drauf an ob man ne lib oder ne Anwendung macht.


  • Mod

    @Tyrdal sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    @SeppJ sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Und ABIs interessieren bei Designfragen inwiefern?

    Kommt drauf an ob man ne lib oder ne Anwendung macht.

    Was soll das ändern an der Designfrage, was Teil einer öffentlichen Schnittstelle sein sollte und was nicht? Nichts. Du darfst intern deine Klasse gerne PIMPLn, wenn dich stört, dass man abhängige Dinge neu compilieren muss, wenn man irgendwo etwas ändert. Eine Designfrage ist, wie man vermeidet, dass man abhängige Dinge neu programmieren muss, wenn man irgendwo etwas ändert.



  • @SeppJ sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Und ABIs interessieren bei Designfragen inwiefern? Typischer Beitrag von dir, völlig nutzlos, nur um irgendwas vermeintlich klug klingendes zu sagen.

    Das ist wieder eine typische Antwort von Dir, 90% verstanden und an den restlichen 10% scheiterst Du kläglich.

    Die ABI Änderungen, die sich durch Codeänderungen ergeben, erzwingen z.B. für Libraries ein anderes Design. Du willst mir doch nicht ernsthaft erzählen wollen, dass bei Qt o.ä. man bei einem Minor Release die ABI zerbrechen kann, und die Kunden das toll finden? Dieser Umstand ist Design relevant und das sollte ein jeder wissen und anwenden können.


  • Mod

    @john-0 sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    @SeppJ sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Und ABIs interessieren bei Designfragen inwiefern? Typischer Beitrag von dir, völlig nutzlos, nur um irgendwas vermeintlich klug klingendes zu sagen.

    Das ist wieder eine typische Antwort von Dir, 90% verstanden und an den restlichen 10% scheiterst Du kläglich.

    Die ABI Änderungen, die sich durch Codeänderungen ergeben, erzwingen z.B. für Libraries ein anderes Design. Du willst mir doch nicht ernsthaft erzählen wollen, dass bei Qt o.ä. man bei einem Minor Release die ABI zerbrechen kann, und die Kunden das toll finden? Dieser Umstand ist Design relevant und das sollte ein jeder wissen und anwenden können.

    Es geht nicht darum, ob das falsch oder richtig ist, sondern dass das absolut gar nichts mit dem Thema zu tun hat. Du kommst in jeden Thread rein, konstruierst einen Strohmann, der so weit weg geholt ist, dass ganze Astrobiologielehrstühle sich nur damit beschäftigen, und greifst diesen dann an, um dich irgendwie toll zu fühlen, weil du eine Diskussion gewinnst, die aber nur in deinem eigenen Kopf existiert. Sieht man auch wieder toll an deiner Antwort hier, die überhaupt nicht auf irgendetwas eingeht, sondern mir irgendetwas zu Qt in den Mund legen möchte, das du dir wieder zwecks Selbstdarstellung ausgedacht hast. Hat schon seinen Grund, warum so viele der längerfristigen Mitglieder dieses Forums dich auf ihrer Ignoreliste haben. Aber uns Moderatoren nervt es halt einfach nur, und du hilfst halt auch niemandem damit, was eigentlich der Hauptzweck dieses Forums ist. Wahrscheinlich denkst du sogar wirklich, dass andere irgendwie beeindruckt wären von deiner scharfsinnigen Logik und schlagenden Argumenten, wenn sie nichts mehr erwidern, obwohl sie bloß genervt die Augen verdrehen und die durchsichtige Strohmanndiskussion ignorieren.



  • @SeppJ sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    sondern dass das absolut gar nichts mit dem Thema zu tun hat.

    Es geht um das Thema: Wie beeinflusst protected das Design von Klassen in C++. Das Design von C++ Klassen wird eben nicht nur von der API sondern auch von der ABI beeinflusst. Das könnte man nun akzeptieren, und als Ergänzung zu dem schon Geschriebenem akzeptieren. Dir fällt nichts besser ein zu wiederholten Mal eine Metadiskussion zu starten. Weshalb fällt es dir so schwer persönliche Angriffe zu unterlassen?


  • Mod

    @SeppJ hat Recht: Durch protected erschafft man eine Abhaengigkeit zum (protected) Interface. Abhaengigkeiten zu Implementierungsdetails sind aber die #1 Motivation dafuer, ueberhaupt private zu haben. Deshalb ergibt protected i.d.R. nur bei Hilfsmembern Sinn.

    @john-0 Wie viele Leute muessen Dir Deine perniziösen Verhaltensmuster noch psychoanalysieren, bevor Du mal anfaengst zu reflektieren? Unabhaengig davon, ob irgendwelche nuetzlichen Erkenntnisse in Deinen Posts enthalten sind: Jeder Thread mit Dir artet in eine passiv-aggressive Spirale von irrelevanten Seitenthemen aus, ohne am Ende noch Mehrwert zu bieten. Frag Dich mal, ob das Resultat mit Deinen (hoffentlich aufrichtigen) Intentionen übereinstimmt.



  • @Columbo

    Es wird sich hier im Forum immer wieder geäußert, dass so wenige Nutzer sich länger im Forum engagieren. Dreimal darfst du raten, weshalb das der Fall ist. Glaubst du ernsthaft normale Menschen haben Lust auf diese fortgesetzte verbalen Entgleisungen(1) der Mods in diesem Forum?

    (1) Dir fällt auch nichts besseres ein als im erstes Posting mir gleich ein krankhaftes Verhalten anzudichten.

    Ich kenne so ein Verhalten nur aus dem Usenet, von einer bestimmten Person mit Kürzel Fefe. Aber Fefe war für sachliche Argumente zugänglich.

    P.S. Wenn du mich nicht im Forum haben willst, schreib das einfach, anstatt mich jedesmal anzupöbeln.



  • @john-0 sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    länger im Forum engagieren...Glaubst du ernsthaft normale Menschen haben Lust auf diese fortgesetzte verbalen Entgleisungen(1) der Mods in diesem Forum?

    Ich bin seit 2009 registriert und war davor schon ein paar Jahre nicht registriert unterwegs (ging damals noch). Ich kann mich an keine nenneswerte Entgleisung eines Mods erinnern.

    @john-0 sagte in Klassen in C++ Durchschnitt von zwei Zahlen berechnen:

    Wenn du mich nicht im Forum haben willst, schreib das einfach, anstatt mich jedesmal anzupöbeln.

    Wenn dich jemand nicht im Forum haben wollte, dann hätte sich @SeppJ wohl nicht extra die Mühe gemacht, mal zu schreiben, warum deine Antworten soooo anstrengend sind.


Anmelden zum Antworten