set-Container in einer h-Datei deklarieren?



  • Hi Leute!

    Ich möchte einen set-Container in einer h-Datei mit meinem eigenen Datentypen "person" deklarieren. Laut compiler bekomme ich da aber einige Fehler, unter anderem, dass ; vor dem Operator < fehlt. Ich weiß ehrlich gesagt nicht was ich da so falsch gemacht haben soll:

    #ifndef VERWALTUNG__H
    #define VERWALTUNG__H
    
    #include<set>
    #include"person.h"
    
    class verwaltung
    {
    private:
    	char* faName;
    	set<person> mitarbeiter;
    
    public:
    	verwaltung(void);
    	~verwaltung(void);
    
    	void addMitarbeiter(person p);
    	/*void entlasseMitarbeiter();
    	void gehaltMitarbeiter();
    	void druckeMitarbeiter();
    	void berechneKosten();*/
    };
    
    #endif
    


  • **std::**set



  • Oh, das hätt ich selber wissen können. Leider.

    Naja jetzt mosert der Compiler jedenfalls, dass person nicht deklariert sei.



  • Wahrscheinlich zu recht. Aber ohne den Inhalt von person.h zu kennen, kann man das nicht beurteilen.



  • MandarfauchLeerzeichenbeimIncludemachen.



  • @Bashar:

    Hier ist die Person.h:

    #ifndef PERSON__H
    #define PERSON__H
    #include "verwaltung.h"
    
    class person
    {
    public:
    	char* name;
    	char* wohnort;
    	unsigned int gehalt;
    
    	person(void);
    	~person(void);
    
    	void setName(char* inputName);
    	void setWohnort(char* inputWohnort);
    	void setGehalt(int inputGehalt);
    };
    
    #endif
    


  • Und da hast du auch schon dein Problem: verwaltung.h und person.h inkludieren sich gegenseitig.



  • Hm, ok. Dann muss ich wohl bei Person die inkludierung von Verwaltung rausnehmen. dann bekomm ich nun aber diesen fehler:

    Fehler 6 error C2676: Binärer Operator '<': 'const person' definiert diesen Operator oder eine Konvertierung in einen für den vordefinierten Operator geeigneten Typ nicht c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional 125



  • Naja, das std::set braucht eben einen Vergleichsoperator für die Personen damit es sortieren kann...



  • Da muss ich wohl den operator überladen, oder?



  • Ja

    Aber warum genau willst du denn eigentlich ein std::set benutzen? Wieso reicht ein vector nicht aus?



  • Eine set deshalb weil's die aufgabe vorschreibt...



  • Ich hab mir nun diese methode geschrieben, die verschiedene mitarbeiter in die set einfügen soll:

    void verwaltung::addMitarbeiter(person pers)
    {
    	mitarbeiter.insert(pers);
    }
    

    Wenn ich nun in der main mehrere personen anlege und diese bspw. 3 personen in der verwaltung "zusammenfassen" will, dann funktioniert das soweit, bis eine zweite person zur set hinzugefügt wird. wenn das passieren soll, dann kackt mir das programm mit den Worten "invalid < operator" ab. Ich denke, die Überladung hat dann nicht so funktioniert. Die string.h hab ich natürlich inkludiert. Hier die Überladung:

    int operator < (const person p1, const person p2)	//Überladung, damit die set sortieren kann
    {
    	return strcmp(p1.name, p2.name);
    }
    

  • Mod

    Die Vergleichsoperation eines sets (und überall in der C++-Standardbibliothek) soll true zurückgeben, wenn die Ordnung erfüllt ist, anernfalls false. Nun guck dir mal an, was strcmp wann zurück gibt.

    Das kommt eben vom Mischen von C und C++. Wurde dir schon oft genug gesagt.



  • Ok, SeppJ. Du hast Recht. Ich bin ja momentan eh schon dabei, dass ich C NICHT MEHR mit C++ mische. Das geht halt nicht von jetzt auf gleich; leider. Hier nun die neue Methode:

    int operator < (const person p1, const person p2)	//Überladung, damit die set sortieren kann
    {
    	//Wert größer als 0 zeigt an, dass der Wert des ersten Zeichens im String p1.name welches nicht passt,
    	//größer ist als der Wert des Zeichens im String p2.name.
    	//Wert gleich 0 zeigt an, dass beide Strings gleich lang sind.
    	if(strcmp(p1.name, p2.name) < 0)
    	{
    		return true;	//Wenn Ordnung erfüllt ist, gib true zurück
    	}
    	else
    	{
    		return false;	//Ansonsten false
    	}
    }
    

    Wie hätte ich denn dann den Operator überladen sollen wenn ich mit der C-Bibliothek string.h in C++ nicht arbeiten soll?


  • Mod

    Mini-Programmierübung: Schreibe eine möglichst kurze Funktion, die das gleiche Ergebnis bei gleicher Eingabe zurück gibt wie foo:

    bool foo(bool b)
    {
      if (b == true)
        return true;
      else if (b == false)
        return false; 
    }
    

  • Mod

    vip@r schrieb:

    Wie hätte ich denn dann den Operator überladen sollen wenn ich mit der C-Bibliothek string.h in C++ nicht arbeiten soll?

    Du sollst eben gleich std::string benutzen. Dann sparst du dir auch den komplizierten Konstruktorrumpf deiner Klassen, den nicht-default Destruktor sparst du ganz ein und es ist außerdem kein Fehler mehr, dass du, wie bisher, den Kopierkonstruktor und den Zuweisungsoperator weggelassen hast.



  • SeppJ schrieb:

    Du sollst eben gleich std::string benutzen.

    Hm, darauf bin ich jetzt gar nicht gekommen. C++ bietet ja in der Tat eine Datentypen string an. Da brauch ich ja dann gar nicht mit char-Pointern arbeiten, oder? Das würde aber dann bedeuten, dass ich meine zwei Klassen in denen ich char-Pointer benutzt habe, auf string umstellen muss, oder?


  • Mod

    vip@r schrieb:

    Das würde aber dann bedeuten, dass ich meine zwei Klassen in denen ich char-Pointer benutzt habe, auf string umstellen muss, oder?

    Ja, wenn man von char* auf string umstellen möchte, dann muss man dazu von char* auf string umstellen.

    Den Vergleichsoperator für Person müsstest du natürlich trotzdem schreiben (oder einen kleinen Lambda-Ausdruck benutzen). Dies geht aber sehr einfach, da string bereits alle Vergleichsoperatoren (mit den in C++ üblichen Konventionen) kennt.



  • Ich möchte jetzt, auch wenn es von der Übung nicht mehr explizit verlangt wird, noch eine Methode schreiben, die mir per Tastaturaufforderung die Möglichkeit bietet Personen anzulegen, schreiben. Bisher habe ich die Personen in der main so wie's unten steht angelegt. Was ich aber nun in meiner neuen Methode nicht ganz verstehe, ist, wie ich einen sich selbst verändernden Variablennamen hinbekomme. Ich denke ihr versteht was ich meine, oder?

    person myPerson1, myPerson2, myPerson3;
    	verwaltung myVerwaltung;
    
    	myPerson1.setName("aaa");
    	myPerson1.setWohnort("bbb");
    	myPerson1.setGehalt(3500);
    	myVerwaltung.addMitarbeiter(myPerson1);
    

Anmelden zum Antworten