Programmkontrolle zum Thema Klassen



  • Hallo Leute,
    Seit ein paar Wochen komme ich wieder regelmäßig dazu etwas für die Programmiererei zu machen.
    Ich arbeite mich dabei im Netz durch ein Tutorial welche mir "gut liegt".

    Ich bin derzeit beim thema Klassen angelang und habe darin noch nicht das sichere gefühl was ich mir wünsche.
    Ich habe einfach mal ein kleines Programm geschrieben welchen nix weiter tun soll als zwei zahlen zu addieren (und das natürlich mit einer kalsse realisiert).

    Ich würde mich freuen wenn ihr mir zu dem nachfolgenden Code mal eure Meinung sagen würdet und mir noch ein paar tipps geben könnten was man noch besser machen kann. Vielen Dank

    Toni

    #include <cstdlib>
    #include <iostream>
    using namespace std;
    
    class summ
    {
          private:
                 int zahl1;
                 int zahl2;
          public:
                 //eingabeprozedur
                 void eingabe()
                 {
                      cout<<"Bitte erste zahl eingeben:"<<endl;
                      cin>>zahl1;
                      cout<<"Bitte zweite Zahl eingaben:"<<endl;
                      cin>>zahl2;
                 };
                 //berechnungsprozedur
                 int berechnung()
                 {
                 int ergebnis;
                 ergebnis=zahl1+zahl2;
                 return ergebnis;
                 };
                 //ausgabeprozedur
                 int ausgabe()
                {
                cout<<"Die Summe von "<<zahl1<<"+"<<zahl2<<" ist gleich "<<berechnung() <<endl; 
                };
    };
    int main(int argc, char *argv[])
    {summ s;
        s.eingabe();
        s.berechnung();
        s.ausgabe();
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    


  • Hallo,
    das sieht auf den ersten Blick ganz ok aus, mit ein paar Schönheitsfehern.
    Du könntest noch eine summ.h mit den Deklarationen und eine summ.cpp mit den Methoden-Defintionen machen.
    Ansonsten hab ich noch ein paar Schönheitsfehler korrigiert, die Erklärungen findest du im Code:

    #include <iostream>
    using namespace std;
    
    class summ
    {
          private:
                 int zahl1;
                 int zahl2;
          public:
                 //eingabeprozedur
                 void eingabe()
                 {
                      cout << "Bitte erste zahl eingeben:\n";
                      cin >> zahl1;
                      cout << "Bitte zweite Zahl eingaben:\n";
                      cin >> zahl2;
                 } //semikolon ist hier unnötig
                 //berechnungsprozedur
                 int berechnung()
                 {
    				 return zahl1+zahl2; //so gehts einfacher
                 }
                 //ausgabeprozedur
                void ausgabe() //sie gibt ja nichts zurück, also void
                {
                    cout << "Die Summe von " << zahl1 << "+" << zahl2 << " ist gleich " << berechnung() << "\n";
                }
    };
    
    int main( /*Die Parameter benutzt du ja nicht*/ )
    {
        summ s;
        s.eingabe();
        //s.berechnung(); hier passiert ja nichts..
        s.ausgabe();
        //system("PAUSE"); das ist schlecht
        cin.get(); //so ists besser
        return 0;
    }
    


  • Mal salopp gesagt: In eine Klasse sollten nur Daten und darauf angewandte Funktionen (Methoden) kommen. Die Benutzerschnittstelle für die Dateneingabe gehört dann nicht in die Klasse. Du solltest zunächst lernen, was Klassen sind und können. Ist nicht schlimm, so hat jeder einmal angefangen.



  • Dank für die Schnelle Antwort.
    ich fang mal unten an.
    In der Mainfunktion sehe ich leider erst jetzt das ich s.berechnung einsparen könnte.
    es wird ja schließlich in der Ausgabeprozedur aufgerufen.

    Das system("PAUSE"); hat die IDE (Dev C++ portable) eingeworfen.
    ich habe sonst immer mit cin<<z; auf eine unbenutzte variable gewarten. (sonst ist das fenster einfach zugegangen)
    die alternative hast du ja angemerkt.

    Was die Deklarationen und Methoden betrifft:

    ist das so gemeint das ich alles was in private: steht in summ.h
    und was in public: steht in summ.cpp fassen soll und das an der stelle einbinden?
    Könnte ich nicht auch die ganze klasse in eine summ.h einlagern und dann einfach oben mit einbinden?

    Mfg

    Toni



  • ToniThiele schrieb:

    Was die Deklarationen und Methoden betrifft:

    ist das so gemeint das ich alles was in private: steht in summ.h
    und was in public: steht in summ.cpp fassen soll und das an der stelle einbinden?
    Könnte ich nicht auch die ganze klasse in eine summ.h einlagern und dann einfach oben mit einbinden?

    Nein, so ist das nicht gemeint, sondern so:
    - Deklarationen (Bekanntmachungen) kommen in die Header-Datei.
    - Definitionen kommen dann in die cpp-Datei.

    Header

    #ifndef SUMM_H
    #define SUMM_H
    
    class summ
    {
          private:
                 int zahl1;
                 int zahl2;
          public:
                 summ(int,int);
                 int berechnung();
    };
    
    #endif
    

    cpp

    #include "summ.h"
    
    summ::summ(int z1, int z2) : zahl1(z1), zahl2(z2)
    {
    }
    
    int summ::berechnung()
    {
        return zahl1+zahl2;
    }
    

    main

    #include <iostream>
    #include "summ.h"
    
    int main()
    {
        summ s(5,7);
        std::cout << s.berechnung();   
    
        std::cin.get();
        return 0;
    }
    

    lg



  • Ich hab noch eine kleine sache die mich verwirrt.
    Wieso nehmen wir nicht weiter die variablen zahl1 & zahl2 ?
    Da ich denke das du einen guten grund dafür hast das so es so machst und nicht anders hab ich noch die bitte das du mal genau schreibst was die zeitle tut.
    Ich nehme an hier erfolgt die zuweisung zwischen z1 und zahl1 ...
    Ich seh aber trotzdem nicht durch. und warum summ:summ?

    sorry für die doofen fragen.

    #include "summ.h"
    
    summ::summ(int z1, int z2) : zahl1(z1), zahl2(z2)
    //Kannst du mal beschreiben was diese Zeile macht...?
    
    {
    }
    
    int summ::berechnung()
    {
        return zahl1+zahl2;
    }
    


  • Huhu,
    also ich werde mal versuchen, dir ein paar Dinge zu erklären:

    - Jede Klasse hat einen Konstruktor, falls du selbst keinen angibst, generiert der Compiler einen, den sog. Standardkonstrukor (er erwartet keine Parameter).

    - Ein Konstruktor hat kein Rückgabedatentyp, sondern beginnt direkt mit dem Namen (Name = Klassenname), gefolgt von der Parameterliste.

    - In meinem Beispiel habe ich nun einen Konstruktor definiert, der 2 Parameter erwartet ... 2 Integer-Variablen

    summ(int,int); // Deklaration --> Dem Compiler etwas bekannt machen.
    
    summ::summ(int z1, int z2) : zahl1(z1), zahl2(z2) // Definition --> definieren, was die Methode machen soll.
    {
    }
    

    - Den ::, den du da siehst, ist der sog. Scope-Operator. Er spezifiziert die Zugehörigkeit.

    // Zugehörigkeit::Attribut/Methode
    summ::summ(inz z1, int z2) ... // Der Konstruktor heißt summ und gehört zu der Klasse summ.
    

    - Nun hat die Klasse summ ja 2 Attribute, zahl1 und zahl2, die du natürlich initialisieren solltest, sonst haben sie irgendeinen Wert.

    // Der Konstruktor wird aufgerufen, und der Parameter z1 ist 5, und z2 ist 7.
    // Mit diesen 2 Paramtern initialierst du nun die Attriubte (zahl1 und zahl2), mittels der Initialisierungsliste.
    summ s(5,7);
    

    - Die Initialisierungsliste wird mit dem einfachen Doppeltpunkt eingeleitet.

    ... : zahl1(z1), zahl2(z2) // Initialisierung findet hier statt: zahl1 erhält den Wert von z1, und zahl2 erhält den Wert von z2.
    

    - Jetzt denkst du vielleicht, wieso so kompliziert und nicht einfach:

    summ::summ(int z1, int z2) // Nun findet hier nur noch die Definition der Attribute statt.
    {
        zahl1 = z1; // Zuweisung
        zahl2 = z2; // Zuweisung
    }
    

    Zwischen der Initialisierungsliste und dieser Variante gibt es aber gravierdene Unterschiede. Hier initialisierst du nämlich nicht deine Attribute, sondern definierst sie und weist ihnen danach etwas zu, d.h. du benötigst 2 Operationen.
    Mittels der Initialisierungsliste brauchst du nur 1 Operation, nämliche die Initialisierung, die Definition+Zuweisung in einem Rutsch macht.

    lg



  • Hi,
    das nenn ich mal ne ausführliche erläuterung.

    So macht das ganze natürlich sinn. Werd aber trotzdem noch e bisschen üben müssen um das ganz zu verinnerlichen.

    Vielen dank für die Hilfe.

    Mfg

    Toni


Anmelden zum Antworten