Nachrichten Klasse



  • Hallo, ich habe ein problem undzwar erhalte ich eine Fehlermeldung wenn ich den Destruktor der Nachrichten Klasse Aufrufe nun weiß ich nicht wie ich ihn gestalten muss.

    Nachricht Header:

    #ifndef INCLUDED_NACHRICHTEN
    #define INCLUDED_NACHRICHTEN
    #include <string>
    #include <set>
    #include <iostream>
    #include "Ordner.h"
    using namespace std;
    
    class Ordner;
    class Nachricht
    {
    	friend Ordner;
    public:
    	// konstruktoren und destruktoren
    	explicit Nachricht(const string&); 
    	Nachricht(const Nachricht&);
    	Nachricht& operator=(const Nachricht&);
    	~Nachricht();
    
    	void _save(Ordner&); // speicher ordner 
    	void _remove(Ordner&); // entferne ordner
    private:
    	void save_ordner(Ordner&); // speicher dieses objekt in ordner
    	void remove_ordner(Ordner&); // entferne dieses objekt aus ordner
    	void remove_alles(); // alle zeiger auf das aktuelle objekt löschen
    
    	string nachricht; // nachricht mit dem textinhalt
    	set<Ordner*> Nachricht_im_Ordner; // ordner in denen sich die nachricht befindetA
    };
    #endif
    

    Nachricht_t.cpp

    #include"Nachricht.h"
    
    Nachricht::Nachricht(const string& str) : nachricht(str)
    {
    }
    Nachricht::Nachricht(const Nachricht& rhs)
    {
    	if (this != &rhs)
    	{
    		nachricht = rhs.nachricht;
    		Nachricht_im_Ordner = rhs.Nachricht_im_Ordner;
    		// schreibe die adresse des aktuelle objekts in jeden ordner
    		for (auto every_ordner : Nachricht_im_Ordner)
    		{
    			every_ordner->ordner_nachricht.insert(this);
    		}
    	}
    }
    Nachricht& Nachricht::operator=(const Nachricht&rhs)
    {
    	if (this != &rhs)
    	{
    		nachricht = rhs.nachricht;
    		Nachricht_im_Ordner = rhs.Nachricht_im_Ordner;
    		// schreibe die adresse des aktuelle objekts in jeden ordner
    		for (auto every_ordner : Nachricht_im_Ordner)
    		{
    			every_ordner->ordner_nachricht.insert(this);
    		}
    	}
    	return *this;
    }
    Nachricht::~Nachricht()
    {
    	remove_alles();
    }
    
    // Save und Remove Methoden
    void Nachricht::_save(Ordner& rhs)
    {
    	rhs.ordner_nachricht.insert(this);
    	save_ordner(rhs);
    }
    void Nachricht::save_ordner(Ordner& rhs)
    {
    	Nachricht_im_Ordner.insert(&rhs);
    }
    void Nachricht::_remove(Ordner& rhs)
    {
    	rhs.ordner_nachricht.erase(this);
    	remove_ordner(rhs);
    }
    void Nachricht::remove_ordner(Ordner& rhs)
    {
    	Nachricht_im_Ordner.erase(&rhs);
    }
    // ---Remove alles---
    void Nachricht::remove_alles()
    {
    	for (auto single : Nachricht_im_Ordner)
    	{
    		// entferne zeiger auf diese klasse
    		single->ordner_nachricht.erase(this);
    	}
    	Nachricht_im_Ordner.clear();
    }
    

    Ordner Header Klasse

    #ifndef INCLUDED_ORDNER
    #define INCLUDED_ORDNER
    
    #include <iostream>
    #include <string>
    #include <set>
    #include "Nachricht.h"
    using namespace std;
    class Nachricht; 
    
    class Ordner
    {
    	friend Nachricht;
    public:
    	// konstruktoren und destruktoren
    	Ordner(const string&);
    	Ordner(const Ordner&);
    	Ordner& operator=(const Ordner&);
    	~Ordner();
    
    	void _save(Nachricht&); // speicher eine nachricht in ordner_nachricht ab
    	void _remove(Nachricht&); // entferne eine nachricht aus ordner_nachricht
    	void _ausgabe(); // inhalt ordner ausgeben
    private:
    	void save_ordner(Nachricht&); // speicher die adresse des aktuellen objekts in der übergebenen nachricht von save
    	void remove_ordner(Nachricht&); // entferne die adresse des aktullen objekts aus dem set<Ordner*> bereich 
    	void remove_alles(); // alle zeiger auf das aktuelle objekt entfernen
    
    	// die nachricht die im folgenden ordner gespeichert werden sollen
    	string ordner_name; // name des ordners
    	set<Nachricht*> ordner_nachricht;
    };
    
    #endif
    

    Ordner_t.cpp

    #include "Ordner.h"
    
    Ordner::Ordner(const string& str) : ordner_name(str)
    { 
    }
    Ordner::Ordner(const Ordner& rhs)
    {
    	if (this != &rhs)
    	{
    		ordner_nachricht = rhs.ordner_nachricht;
    		for (auto single : ordner_nachricht)
    		{
    			single->Nachricht_im_Ordner.insert(this);
    		}
    	}
    }
    Ordner& Ordner::operator=(const Ordner& rhs)
    {
    	if (this != &rhs)
    	{
    		ordner_nachricht = rhs.ordner_nachricht;
    		for (auto single : ordner_nachricht)
    		{
    			single->Nachricht_im_Ordner.insert(this);
    		}
    	}
    	return *this;
    }
    Ordner::~Ordner()
    {
    	remove_alles();
    }
    
    // Save und Remove Methoden
    void Ordner::_save(Nachricht& rhs)
    {
    	rhs.Nachricht_im_Ordner.insert(this);
    	save_ordner(rhs);
    }
    void Ordner::save_ordner(Nachricht& rhs)
    {
    	ordner_nachricht.insert(&rhs);
    }
    void Ordner::_remove(Nachricht& rhs)
    {
    	rhs.Nachricht_im_Ordner.erase(this);
    	remove_ordner(rhs);
    }
    void Ordner::remove_ordner(Nachricht&rhs)
    {
    	ordner_nachricht.erase(&rhs);
    }
    
    // ---Remove Alles---
    void Ordner::remove_alles()
    {
    	for (auto single : ordner_nachricht)
    	{
    		single->Nachricht_im_Ordner.erase(this);
    	}
    }
    
    void Ordner::_ausgabe()
    {
    	cout << endl <<  "Inhalt des Ordners " << ordner_name << ':' << endl;
    	for (auto single : ordner_nachricht)
    	{
    		cout << single->nachricht << endl;
    	}
    }
    

    Main.cpp

    #include "Nachricht.h"
    #include "Ordner.h"
    
    int main()
    {
    	Ordner Spam("Spam"); Ordner Wichtig("Wichtig"); Ordner NeueNachrichten("Neue Nachrichten");
    
    	Nachricht Message1("Herzlichen Glückwunsch sie haben 1902€ gewonnen!");
    	Nachricht Message2("Willkommen beim Windows Messanger dienst!");
    	Nachricht Message3("Kantana Mt2 hat den D2 eingeführt!");
    
    	NeueNachrichten._save(Message1); NeueNachrichten._save(Message2); NeueNachrichten._save(Message3);
    	Spam._save(Message3);
    	Wichtig._save(Message2);
    
    	Spam._ausgabe(); Wichtig._ausgabe(); NeueNachrichten._ausgabe();
    
    	// Spam.~Ordner(); <-- Fehler
    
    	system("pause");
    }
    


  • TemplateQ schrieb:

    Hallo, ich habe ein problem undzwar erhalte ich eine Fehlermeldung wenn ich den Destruktor der Nachrichten Klasse Aufrufe

    Es ist der Job des Compilers die Destruktoren von Objekten aufzurufen, nicht deiner.

    Generell bitte Fehlermeldung nennen und Code Debuggen 😉



  • Fehlermeldung:
    Debug Assertion Failed!
    Expression: map/set iterator not incrementable

    Ursache dafür:

    void Ordner::remove_alles()
    {
       -->	for (auto single : ordner_nachricht)
    	{
    		for (auto it : single->Nachricht_im_Ordner)
    		{
    			it->ordner_nachricht.erase(single);
    		}
    	}
    	ordner_nachricht.clear();
    }
    


  • Du sollst den Destruktor auch nicht aufrufen, das geschieht automatisch!
    Überhaupt ist dein Design komisch, die beidseitige friend Abhängigkeit zwischen Nachricht und Ordner ist sehr schlecht, zyklische Abhängigkeiten sollte man vermeiden. Und Destruktor, Copy-Ctor und Copy-Assignment solltest du auch nicht brauchen, weil der Default bereits das richtige für dich macht.



  • Naja, der Default Copy Constructor macht schon einiges, jedoch muss ich zusätzlich noch die Adresse des Aktuellen Objects in die gewünschte Klasse einfügen und das tut er nicht deshalb habe ich ihn selbst konstruiert.
    Meine Frage ist nun wieso ich das Objekt nicht löschen kann 😕
    Ich habe schon verstanden, dass man das dem Compiler überlassen sollte. 🙂



  • void Ordner::remove_alles() 
    { 
        -->  for (auto single : ordner_nachricht) 
         { 
             for (auto it : single->Nachricht_im_Ordner) 
             { 
                 it->ordner_nachricht.erase(single); 
             } 
         } 
         ordner_nachricht.clear(); 
    }
    

    Was ist dir jetzt nicht klar?
    Du kannst nicht einfach den "aktuellen" Eintrag in einem std::set löschen über das du gerade drüberiterierst.
    Davon abgesehen würde der Code nichtmal Sinn machen, selbst wenn er funktionieren würde. Weil er nicht das macht was du machen willst. Bzw. machen solltest.

    Und...

    remove_alles

    lol



  • Genau das wollte ich wissen. Ich wusste nicht das man einen eintrag ausm set nicht einfach so löschen kann. Dankeschön 👍

    Welche möglichkeit gibt es denn um einen Eintrag zu entfernen innerhalb einer for schleife?

    Ja, ich bin noch nicht sogut darin mir ordentliche variablennamen auszudenken die nicht allzu lang sind.^^



  • Es hat sich erledigt ich, ich habe mithilfe meines des buches rausgefunden
    undzwar muss ich die adresse aus den jeweiligen ordnern rauslöschen und dann

    clear anwenden um meine eigenen einträge zu löschen


Anmelden zum Antworten