Klassen und Objekte: Objekte in Arrays ablegen



  • Guten Nachmittag liebe Community,
    Ich soll im Rahmen einer Übungsaufgabe eine Klasse erstellen die 4 Attribute besitzt. Darunter welche mit int und string Typen:

    class Customer {
    private:
    	int number;
    	string name;
    	int postCode;
    	string domicile;
    public:
    	Customer();
    	Customer(int numb, string name, int plz, string dom);
    	~Customer() {};
    	void read();
    	string toString();
    };
    

    Im folgenden soll ich 5 Objekte erstellen und diese manuell über die Tastatur eingeben lassen. Hier sieht mein Ansatz wie folgt aus:

    void Customer::read()
    {
    	srand(time(0));
    	int number;
    	string name;
    	int postCode;
    	string domicile;
    
    	cout << "Bitte geben sie in dieser Reihenfolge folgende Daten an: 'Vorname Nachname'; 'Postleitzahl'; 'Wohnort'." << endl;
    	getline(cin, name);
    	cin >> postCode;
    	getline(cin, domicile);
    	this->name = name;
    	this->postCode = postCode;
    	this->domicile = domicile;
    	number = (rand() * 100 % 900000) + 100000;
    	this->number = number;
    }
    

    Die Aufgabe ist nun, diese Objekte in ein Array zu packen, und genau hier liegt mein Problem. Ich habe zwar einen Ansatz:

    int main() {
    	Customer Cust1;
    	Customer Cust2(13216, "Max Musti", 32321, "Dresden");
    	Customer Cust3, Cust4, Cust5;
    	Cust3.read();
    	Cust4.read();
    	Cust5.read();
    
    	Customer* array = new Customer[5];
    
    	array[0] = Cust1;
    	array[1] = Cust2;
    	array[2] = Cust3;
    	array[3] = Cust4;
    	array[4] = Cust5;
    

    aber ich erhalte sehr unsinnige Ergebnisse wenn ich den Code laufen lasse. (Da fehlt noch Code, aber der ist irrelevant für das Problem). Ich hoffe ihr könnt mir helfen ^^

    MfG Tim.



  • @Qualitaetsbemme sagte in Klassen und Objekte: Objekte in Arrays ablegen:

    wenn ich den Code laufen lasse

    Den Code kann man nicht laufen lassen. Er enthält auch nichts, das irendwelche Ergebnisse (ob sinnig oder unsinnig) hätte.

    @Qualitaetsbemme sagte in Klassen und Objekte: Objekte in Arrays ablegen:

    Da fehlt noch Code, aber der ist irrelevant für das Problem

    Offensichtlich nicht,



  • #include <iostream>
    #include <sstream>
    #include <ctime>
    #include <string>
    using namespace std;
    
    //----------------------- class declaration -------------------------
    class Customer {
    private:
    	int number;
    	string name;
    	int postCode;
    	string domicile;
    public:
    	Customer();
    	Customer(int numb, string name, int plz, string dom);
    	~Customer() {};
    	void read();
    	string toString();
    };
    
    //---------------------- Definition/Implementation of Methods -------
    // default/parameterless constructor
    Customer::Customer()
    {
    	this->number = 12345;
    	this->name = "Mareike Hasse";
    	this->postCode = 39108;
    	this->domicile = "Magdeburg";
    }
    
    // complete Constructor
    Customer::Customer(int numb, string name, int plz, string dom)
    {
    	this->number = numb;
    	this->name = name;
    	this->postCode = plz;
    	this->domicile = dom;
    }
    
    // all attrubutes are reading of keyboard
    void Customer::read()
    {
    	srand(time(0));
    	int number;
    	string name;
    	int postCode;
    	string domicile;
    
    	cout << "Bitte geben sie in dieser Reihenfolge folgende Daten an: 'Vorname Nachname'; 'Postleitzahl'; 'Wohnort'." << endl;
    	getline(cin, name);
    	cin >> postCode;
    	getline(cin, domicile);
    	this->name = name;
    	this->postCode = postCode;
    	this->domicile = domicile;
    	number = (rand() * 100 % 900000) + 100000;
    	this->number = number;
    }
    
    // returns a "nice" string consisting of attributes
    string Customer::toString()
    {
    	stringstream s;     // stream from  sstream.h
    	s << endl << "____________ Person___________" << endl
    		<< number << endl
    		<< name << endl
    		<< postCode << endl
    		<< domicile << endl
    		<< "______________________________" << endl;
    	return s.str(); // convert stream ss into a string
    }
    
    //------------------- definition of functions -----------------------
    Customer getWinner(Customer dat[5])
    {
    	srand(time(0));
    	int n = rand() % 4;
    	return dat[n];
    }
    
    //---------------------- main()-function ----------------------------
    int main() {
    	Customer Cust1;
    	Customer Cust2(13216, "Max Musti", 32321, "Dresden");
    	Customer Cust3, Cust4, Cust5;
    	Cust3.read();
    	Cust4.read();
    	Cust5.read();
    
    	Customer* array = new Customer[5];
    
    	array[0] = Cust1;
    	array[1] = Cust2;
    	array[2] = Cust3;
    	array[3] = Cust4;
    	array[4] = Cust5;
    
    	for (int i = 0; i < 5; i++) {
    		cout << array[i].toString() << endl;
    	}
    	
    	cout << "Der zufällige Gewinner ist: " << getWinner(array).toString() << endl;
    
    	return 0;
    }
    
    


  • @Qualitaetsbemme sagte in Klassen und Objekte: Objekte in Arrays ablegen:

    Customer* array = new Customer[5];

    Dazu 2 Anmerkungen:
    Warum nicht einfach:

    Customer array[5];
    

    Außerdem ist der Name 'array' unglücklich gewählt, weil es auch ein std::array gibt.



  • @manni66 Hier ist der komplette Code -.-...
    Ich meinte den Compiler laufen lassen.



  • @Belli Jetzt gibt der Compiler schon etwas sinnvolleres aus. Jedoch kann ich bei den Cust3 bis Cust5 nur 2 Attribute statt 3 eingeben, obwohl ich doch in void read() nach 3 frage...
    Ansonsten danke schonmal ^^



  • Es ist nicht ganz unproblematisch, formatierte und unformatierte Eingabe zu mischen (cin und getline).
    Da die Postleitzahl als int sowieso nicht korrekt ist (es gibt glaube ich auch PLZen die mit 0 beginnen), vereinbare die PLZ als string und nicht als int, und nimm zum Einlesen durchgehend getline.



  • @Belli Danke! Jetzt funktioniert es.
    Schöne Restwoche und vielen Dank ^^



  • Dein Code hat diverse Probleme:

    1. Du hast einen Destruktor von Customer, dieser ist aber leer -> wozu also überhaupt einen schreiben, lass ihn weg!
    2. Du benutzt "new". Das ist eine schlechte Idee im allgemeinen und hier im Besonderen, weil du kein korrespondierendes "delete[]" hast. Du hast also ein Speicherleck und zerstörst deine Customer sowieso nicht ordentlich.
    3. Du benutzt "using namespace std;". Kann man machen, würde ich aber von abraten. Insbesondere weil es auch in C++ Arrays gibt, die std::array heißen, also dann, wenn du das "using namespace std" benutzt, mit deiner Variablen namens Array kollidieren.
    4. Das Array. Verwende in C++ nicht das C-Style Array (welches, wie der Name sage, von C kommt) - sondern nutze stattdessen in C++ bevorzugt std::array (für eine feste Zahl Elemente) oder std::vector (wenn variabel viele Elemente). Also statt Customer* array = new Customer[5]; nimmst du std::array<Customer, 5> my_array - oder wohl besser, wenn du dich nicht auf 5 festlegen und sofort erzeugen willst: std::vector<Customer> my_vector. Du brauchst auch kein new - und mit vector landen deine Customer-Objekte dann trotzdem im Freispeicher (bei array nicht).
    5. Schau dir mal an, wie man den operator<< überladen kann. Dann brauchst du das toString nicht mehr.
    6. Es ist oft vorteilhaft, Objekt-Variablen (wie string) als const & an Funktionen zu übergeben.
    7. Seit die bewusst, dass die 5 in Customer getWinner(Customer dat[5]) keine Bedeutung hat! Das ist ein Problem dieser C-Arrays, das du mit ohne wohl nicht hättest. Deine getWinner-Funktion gibt dann eine Kopie des Gewinners zurück. Ist das wirklich das, was du willst?
    8. a) srand ruft man 1x im Programm auf, nicht 1x pro Funktion
      b) rand % 4 liefert Werte von 0 bis 3. Der Customer[4] wird also nie gewinnen...
      c) srand/rand sind Funktionen aus C. In C++ kannst du stattdessen den Header <random> nebst einer std::uniform_int_distribution verwenden.
    9. alles, was ich nicht erwähnt habe 🙂

Anmelden zum Antworten