Problem mit List, Iterator und Pointern auf Objekte



  • Wenn ich schnell richtig geguckt habe, verletzen all deine Klassen, also insbesondere auch CSprite und CText, die Dreierregel.

    Es gab gerade in https://www.c-plusplus.net/forum/topic/349894/programm-stürzt-nach-korrekter-ausgabe-ab/ eine ausführliche Diskussion über das Problem. Bitte lies das und versuche zu verstehen, was bei dir warum problematisch ist und wie es besser geht.



  • /*
    die Aufgabe lautete wie folgt: "Implementieren Sie eine Klasse Student, die einen Namen, Vornamen (beides als char*), eine Matrikelnummer und das Fachsemester (beides unsigned int) enthält. 
    Implementieren Sie eine weitere Klasse Verwaltung, die ein Array von Studenten enthält. Diese Klasse soll neue Studenten anlegen..."
    */
    
    #include <iostream>
    #include <list>
    
    class Student {
    public:
    	Student(const char ChVorname[], const char ChName[], unsigned int nMartikelnummer, unsigned int nFachsemester);
    	~Student();
    	void Ausgabe() {
    		std::cout << pVorname << " " << pName << std::endl;
    	}
    private:
    	const char* pVorname;
    	const char* pName;
    	unsigned int m_nMartikelnummer;
    	unsigned int m_nFachsemester;
    };
    
    Student::Student(const char ChVorname[], const char ChName[], unsigned int nMartikelnummer, unsigned int nFachsemester){
    	pVorname = ChVorname;
    	pName = ChName;
    	m_nMartikelnummer = nMartikelnummer;
    	m_nFachsemester = nFachsemester;
    
    }
    
    Student::~Student() {
    
    }
    
    class Verwaltung {
    public:
    	Verwaltung(unsigned int nAnzahlStudenten);
    	~Verwaltung();
    	void Ausgabe();
    private:
    	unsigned int m_nAnzahlStudenten;
    	std::list<Student> m_StudentenListe;
    	std::list<Student>::iterator m_Student;
    };
    
    Verwaltung::Verwaltung(unsigned int nAnzahlStudenten) {
    
    	m_nAnzahlStudenten = nAnzahlStudenten;
    
    	char chVorname[100];
    	char chName[100];
    	int nMartikelnummer = 0;
    	int nFachsemester = 0;	
    
    	for (unsigned int i = 0; i < m_nAnzahlStudenten; i++) {
    		std::cout << std::endl << "Vorname:";
    		std::cin >> chVorname;
    		std::cout << std::endl << "Name:";
    		std::cin >> chName;
    		std::cout << std::endl << "Martikelnummer:";
    		std::cin >> nMartikelnummer;
    		std::cout << std::endl << "Fachsemester:";
    		std::cin >> nFachsemester;
    
    		Student StudentX(chVorname, chName, nMartikelnummer, nFachsemester);
    		StudentX.Ausgabe();
    		m_StudentenListe.push_back(StudentX);
    	}
    	
    }
    
    Verwaltung::~Verwaltung() {
    	for (m_Student = m_StudentenListe.begin(); m_Student != m_StudentenListe.end(); ++m_Student) {
    		m_Student = m_StudentenListe.erase(m_Student);
    	}
    }
    
    void Verwaltung::Ausgabe() {
    	for (m_Student = m_StudentenListe.begin(); m_Student != m_StudentenListe.end(); ++m_Student) {
    		m_Student->Ausgabe();
    	}
    }
    
    int main()
    {
    	Verwaltung Univerwaltung(2);
    	Univerwaltung.Ausgabe();
    }
    
    

    Ich habe mir das mal durchgelesen und versucht eine Lösung zu finden. Dies ist mein Lösungsansatz für das Problem aus dem anderen Beitrag. Und hier verstehe ich nun nicht warum es keine Ausgabe gibt.



  • @_andi84

    keine Ausgabe

    Keine? Glaub ich nicht.



  • @_andi84 Stand in dem anderen Beitrag nicht auch irgendwo, dass die Aufgabe sch**** ist?

    Schmeiß erstmal alles char* und char[] weg und ersetze sie durch std::string. Dann ersetz std::list durch std::vector.
    Außerdem schmeißt du noch deine Custom Destruktoren weg.

    Dann guckst du dir mal Range based loops an.



  • Ich wollte insbesondere auf die Dinge hinaus, die @SeppJ dort geschrieben hatte. Also zur Resourcenverwaltung.

    Bei dir konkret ist das Problem gewesen, dass du im Konstruktor das SDL-Objekt erzeugst mit irgend so einer SDL-Funktion (das entspricht einem "new") und dann im Destructor das SDL-Destroy (also praktisch ein delete) aufrufst. Wenn du dann dein CSprite kopierst, zerstörst du dasselbe Objekt 2x. Daher unbedingt mal die Dreierregel anschauen. Am besten ist es, wenn du die "Rule of Zero" befolgen kannst (https://en.cppreference.com/w/cpp/language/rule_of_three). Das bedeutet, dass du das SDL-Objekt irgendwie wrappen müsstest. Oder entfernst schnell den Copy-Constructor.

    Ich kenne mich mit SDL allerdings nicht aus - weiß nicht so recht, wie da die normalen Muster aussehen.

    PS: möchte @Schlangenmensch noch unterstützen: warum zur Hölle wollen so viele Neulinge hier std::string nicht nutzen und lieber selbst mit char* herumfrickeln?!


Anmelden zum Antworten