[Solved] "Einführung in die programmierung mit c++" Kapitel 6 Übung Nr.4



  • Hallo ich habe da mal eine Frage.

    Ich arbeite zurzeit am Buch "Einführung in die Programmierung mit C++" von Bjaren Strustrup und komme zurzeit nicht weiter.
    Ich bin zurzeit auf der Seite 237 und mache die Übung Nr.4.

    Aufgabenstellung:
    Definieren Sie eine Klasse Name_value, die einen String und einen Wert enthält. Statten Sie die Klasse mit einem Konstruktor aus (ähnlich wie bei Token). Überarbeiten Sie danach das Programm zu Übung 19 aus Kapitel 4. Statt zweier vector-Container soll es nur noch einen vector< Name_value>-Container verwenden.

    Übung 19 aus Kapitel 4:
    https://pastebin.com/f6ZhUDk5

    Quellcode in dem Token vorkommt:
    https://pastebin.com/RgmdpnA1

    Meine Frage ist jetzt wie soll ich das machen ?
    Was genau soll ich mit dem Konstruktor machen ?
    Und wie soll ich beide Werte in einen vector bekommen, denn es heißt ja " Statt zweier vector-Container soll es nur noch einen vector< Name_value>-Container verwenden" oder habe ich die Übung 19 falsch gemacht ?
    Irgendwie blicke ich da nicht mehr genauer durch.

    LG



  • Der Sinn der Übung ist es eine Klasse für die Speicherung eines Strings zusammen mit einem Wert zu haben, damit man diese gemeinsam in einen Container (z.B. vector) packen kann. In deinem gezeigten Code hast du ja bisher zwei getrennte vector-Objekte (und man muß sicherstellen, daß diese gleichmäßig gefüllt werden).

    Und der Konstruktor dient ja dazu, daß du bei Erzeugung eines Objektes die übergebenen Parameter in den Klassenmembern abspeicherst (so wie es ja die Token-Klasse auch macht), z.B. bei Aufruf von

    Name_value nv("Test", 42);
    

    Schreibe also erst die Name_value-Klasse und dann ändere die main-Funktion, so daß sie nur noch den vector<Name_value>-Container verwendet.



  • @th69
    Mein Problem ist jetzt aber das ich nicht weiß was ich genau in die Klasse schreiben soll.



  • @skailer sagte in Brauche Hilfe zu einer Aufgabenstellung vom Buche "Einführung in die programmierung mit c++":

    @th69
    Mein Problem ist jetzt aber das ich nicht weiß was ich genau in die Klasse schreiben soll.

    die einen String und einen Wert enthält

    Was ist unklar?



  • @manni66
    Allgemein verstehe ich nicht was ich genau in die Klasse schreiben soll und wofür überhaupt der Konstruktor da ist,
    ebenso verstehe ich nicht wie ich mit der main und der Klasse "zusammen arbeite"(Klassen wurden in diesem Kapitel nur grob beschrieben).
    Wie ist es denn möglich das die Klasse einen String und einen wert bearbeitet und dieser dann in einem Vector in der Main ausgegeben wird, ein Vector kann doch nur einen wert speicher oder nicht ?



  • Du brauchst dich doch nur an der Klasse Token orientieren (denn diese besteht ja aus einem charund einem double Wert).
    Verstehst du denn die Klasse und besonders den Konstruktor

    Token(char ch, double val)     // erstelle ein Token aus einem char und einem double
            :kind(ch), value(val) { }
    

    ?

    Ein Vector kann Objekte beliebigen Typs speichern (das was du in den eckigen Klammern angibst), also auch (komplexe) Objekte.
    Wenn du also einen vector<Token> erstellst, dann werden in jedem Vector-Element 2 Werte gespeichert (char kindund double value). Analog sollst du also jetzt einen vector<Name_value>erstellen.

    So verständlicher?



  • @th69
    Okay das habe ich jetzt verstanden.
    Und wie fülle ich den vector von der Main aus mit den beiden werten ?
    Vorher habe ich die einzelnen Datentypen gefüllt und mit einen push_back in den jeweiligen vector gefüllt, wie mache ich das aber jetzt ?



  • Analog, nur daß du eben vorher ein Name_valueObjekt erstellst (s. Code in meinem ersten Beitrag, nur daß du dann die passenden Parameter übergibst) und diesen dann dem Vector hinzufügst.



  • @th69
    Irgendwie werde ich nicht schlau daraus.
    Könntest du es mir in einem Code beispiel vllt verdeutlichen ?



  • Ja , könnte ich, aber was lernst du dabei? Die Kunst des Programmierens ist es auch, aus den Fehlern (z.B. Fehlermeldungen des Compilers) zu lernen.
    Wenn du nicht weiterkommst, dann zeige deinen Code, aber zuerst versuche es mal selber.



  • @th69
    Ich verstehe immer noch nicht wie ich die Parameter übergeben soll.

    In meinem code steht auch noch nichts besonderes, da ich ja nicht weiß wie ich die Parameter übergeben soll.

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    
    class Name_value{
    
      public:
      string name;
      int value;
    
      Name_value(string x)
        :name(x), value(0) {}
    
    };
    
    int main(){
    
      vector<Name_value> erg;
      
       
      return 0;
    }
    . 
    


  • Du kannst ja die while-Schleife zum Einlesen des Namens und des Score aus der Übung übernehmen.
    Bei meinem Code änderst du es so ab, daß anstatt "Test" und 42 eben nameund score übergeben werden (das sind aber Grundlagen, welche schon vorher im Buch erklärt werden).

    Und bei deinem Name_value-Konstruktor fehlt noch der 2. Parameter.



  • Name_value nv(name, score);

    Und was kann ich damit anfangen ?
    Meinen vector kriege ich damit ja dennoch nicht gefüllt.

    vector<Name_value> x;
    
    cin >> nv;
    x.push_back(nv);    // funktioniert ja nicht
    
    

    Oder füllt man den vector anders, ich kenne es nur so.



  • Doch, die Anweisung x.push_back(nv); ist korrekt so (die Variable nvmuß aber natürlich vorher erstellt worden sein), aber die Zeile darüber (so) nicht.

    vector<Name_value> x; // ich würde die Variable eher "name_values", "nvs" o.ä. nennen
    string name;
    int score;
    
    cin >> name >> score;
    
    Name_value nv(name, score);
    x.push_back(nv);
    

    PS: Es ginge auch direkt ohne die explizite Variable nv:

    x.push_back(Name_value(name, score));
    

    (aber das ist etwas schwerer zu lesen)



  • @th69
    Weshalb funktioniert denn die normale Ausgabe nicht wie sonst ?

    vector<Name_value> x;
    .
    .
    .

    cout << x[0];

    Das würde ja eigentlich funktionieren aber wieso nicht jetzt ?



  • @skailer sagte in Brauche Hilfe zu einer Aufgabenstellung vom Buche "Einführung in die programmierung mit c++":

    Weshalb funktioniert denn die normale Ausgabe nicht wie sonst ?

    Weil es für Deinen Typ Name_value keinen Operator << gibt, der auf std::ostream und Name_value passt.

    Da in Deiner Name_value die Daten public sind (was sie aber nicht sein sollten), könnte ein passender Operator so aussehen:

    std::ostream& operator<<(std::ostream & os, Name_value const & nv)
    {
    	os << '\"' << nv.name << "\": " << nv.value;
    	return os;
    }
    


  • @swordfish
    Danke, es funktioniert.
    Muss mich dazu aber nochmal einlese, weil ich überhaupt nicht weiß was das ist 😃



  • @skailer sagte in Brauche Hilfe zu einer Aufgabenstellung vom Buche "Einführung in die programmierung mit c++":

    weil ich überhaupt nicht weiß was das ist

    std::cin ist eine Referenz auf einen std::ostream. Wenn Du nun schreibst

    int foo = 42;
    std::cout << foo;
    

    Dann steht da effektiv ein Funktionsaufruf von

    operator<<(std::cout, foo);
    

    Das heißt, damit man einen int in einen std::ostream (worauf std::cout verweist) schieben kann, braucht es einen Operator <<, der auf seiner linken seite einen std::ostream und auf seiner rechten einen int (oder etwas, in das sich ein int implizit konvertieren lässt) akzeptiert. Praktischerweise bringt die Standardbibliothek solche Operatoren für Basisdatentypen wie char, int, long, float usw. schon mit.

    Handelt es sich beim rechten Operanden von << aber wie in Deinem Fall um einen User-defined-type wie zB eine class, dann musst Du solch einen Operator selbst schreiben.