C++ Klasse, Überladung der Operatoren << und >>



  • Hallo 🙂

    Ich bin neu in diesem Forum und auch Anfängerin in der Programmierung mit C++.

    Ich benötige Hilfe bei der Lösung einer Aufgabe.
    Vielleicht kann jemand von euch mir weiterhelfen.

    Die Aufgabenstellung lautet:
    Erstellen Sie eine Klasse Liste, in der beliebig viele Integerwerte gespeichert werden können. Implementieren Sie die Methoden operator<< und operator>> so, dass Listen formartiert ausgegeben und eingelesen werden können. (Gewünschtes Format für die Darstellung einer Liste mit den drei Werten 1, 2 und 3 als Inhalt ist [1,2,3].)

    Meine ersten 2 Fragen lauten:
    Wenn ich zu Beginn noch nicht weiß wie viele Elemente mein neues Objekt der Klasse Liste enthält, ist ein geeigneter Lösungsansatz wenn mein Konstruktor ein leeres Objekt der Klasse Liste erstellt und dann immer wenn der Operator >> aufgerufen wird ein neues Listenobjekt angelegt wird, dass um eins größer ist als sein Vorgänger?
    Falls ja, stellt sich für mich die Frage wie ich dann am besten meinen Operator >> innerhalb einer Methode überladen kann.
    Eigentlich sieht das dann ja so aus:
    istream& operator>>(int element);
    Oder?
    Das könnte ich innerhalb von einer Methode in meiner Klasse realisieren und benötige keine globale Funktion?

    Freue mich über jeden Denkanstoss.
    Danke im Voraus.

    Mein erster Versuch sieht bisher so aus:

    class Liste{

    private:
    int *elemente;
    int element;
    int counter;

    public:
    Liste();

    Liste operator >> (int element);

    };

    #include<iostream>
    #include "liste.h"
    using namespace std;

    Liste::Liste(){
    this->counter = 0;
    elemente = new int[counter];
    }

    Liste Liste::operator >> (int element){
    Liste neueListe;

    neueListe.elemente = new int[++counter];

    for(int i=0; i < counter; ++i){
    neueListe.elemente[i] = elemente[i];
    }

    neueListe.elemente[counter] = element;

    return neueListe;
    }



  • Benutze doch bitte die CPP Tags für deinen Code.
    Was ist jetzt genau deine Frage?



  • Kannst du mir vielleicht verraten, wie ich meine Textformatierung behalte?
    In meinem Nachrichtentext sind noch alle Einrückungen vorhanden.
    Beim Veröffentlichen sind jedoch diese verloren gegangen.

    Meine Fragen:
    Wenn ich noch nicht weiß wie viele Integerelemente ich speichern möchte, ist es okay meinen Konstruktor mit einem leeren Array zu initialisieren und bei jedem Aufruf von >> die Anzahl der Elemente zu erhöhen?
    Oder gibt es dafür einen besseren Ansatz.

    Obwohl ich den Operator >> überladen möchte, kann ich diesen innerhalb von einer Methode in der Klasse überladen?
    Wenn ich Liste a;
    a >> 3 >> 4 >> 5; realisieren möchte benötige ich doch nach jeder Ausführung
    (a >> 3) einen Rückgabewert vom Objekttyp Liste damit dann
    (a >> 3) >> 4 realisiert werden kann.
    Oder kann ich >> nur innerhalb einer globalen Funktion überladen?



  • Das mit der Formation machst du mit Hilfe der Tags.
    Hier gibt es ne Anleitung: http://www.c-plusplus.net/forum/304133

    Wenn ich noch nicht weiß wie viele Integerelemente ich speichern möchte, ist es okay meinen Konstruktor mit einem leeren Array zu initialisieren und bei jedem Aufruf von >> die Anzahl der Elemente zu erhöhen?
    Oder gibt es dafür einen besseren Ansatz.

    Sicher gibt es dafür bessere Ansätze aber da muss dir jemand anders weiter helfen.



  • Es wird meistens als besser empfunden operatoren als freie Funktionen zu definieren weil es nicht immer als Memberfunktion funktioniert. Das mit dem Rückgabewert Liste des operators geht schon in die richtige Richtung.

    Ich verstehe die Details der Anforderung nicht, aber das sollte eine ordentliche Vorlage sein:

    #include <vector>
    #include <iostream>
    
    struct Liste{
    	Liste &operator << (int i){
    		data.push_back(i);
    		return *this;
    	}
    	std::vector<int> data;
    };
    
    std::ostream &operator << (std::ostream &os, Liste &l){
    	os << '[';
    	if (l.data.size()){
    		for (auto it = std::begin(l.data); it != std::end(l.data) - 1; ++it)
    			os << *it << ',';
    		os << l.data.back();
    	}
    	os << ']';
    	return os;
    }
    
    int main(){
    	Liste l; // <-- Das soll ein kleines L darstellen
    	l << 1 << 2 << 3;
    	std::cout << l << '\n'; // das sollte [1,2,3] ausgeben
    }
    


  • estrella schrieb:

    Obwohl ich den Operator >> überladen möchte, kann ich diesen innerhalb von einer Methode in der Klasse überladen?
    Wenn ich Liste a;
    a >> 3 >> 4 >> 5; realisieren möchte benötige ich doch nach jeder Ausführung
    (a >> 3) einen Rückgabewert vom Objekttyp Liste damit dann
    (a >> 3) >> 4 realisiert werden kann.
    Oder kann ich >> nur innerhalb einer globalen Funktion überladen?

    Du hast meiner Meinung nach die Aufgabe mißverstanden.

    Du schreibst doch im ersten Posting:

    estrella schrieb:

    Implementieren Sie die Methoden operator<< und operator>> so, dass Listen formartiert ausgegeben und eingelesen werden können

    D.h. Du musst das implementieren:

    std::istream& operator>>(std::istream&, Liste&);
    std::ostream& operator<<(std::ostream&, const Liste&);
    

    Ansonsten:
    Deine Idee den Speicher jedesmal zu vergrößern, wenn er voll ist, klingt vielversprechend. Einfach ist natürlich mit jedem neuen Wert einen weiteren slot zu allozieren. Du kannst auch überlegen, den Speicher beispielsweise zu verdoppeln. Das ist etwas komplexer aber nicht so naiv. 😉



  • Vielen Dank für die Unterstützung


Log in to reply