Problem mit Typneudefintion
-
Hey,
ich probiere gerade ein bisschen mit Header Dateien rum und ich komm nicht drauf, wie ich diesen Fehlercode wegbekomme.Fehler C2011 "time_span": "struct" Typneudefinition MeinKalender
Fehler C2011 "Meeting": "class" Typneudefinition MeinKalender
Fehler C2011 "Calender": "class" Typneudefinition MeinKalender
Laut Internet lässt sich das mit #pragma once oder #ifndef #endif lösen, allerdings habe ich diese Befehle in meinem Programm stehen.
Hier der Code
.cpp Datei:#include <iostream> #include <iomanip> #include <vector> #include <stdlib.h> #include <ctime> #include <algorithm> #include "Kalender.h" using namespace std; struct time_span { int fHour; int fMinute; int uHour; int uMinute; }; class Meeting { private: time_span meeting; public: //Termin erstellen ohne Abfrage time_span createMeeting(int fromHour,int fromMinute,int untilHour,int untilMinute) { meeting.fHour = fromHour; meeting.fMinute = fromMinute; meeting.uHour = untilHour; meeting.uMinute = untilMinute; if (checkForAllowedNumber(meeting) == false) { cout << "Error Creating a meeting. Check your numbers!" << endl; } return meeting; } //Termin erstellen mit Abfrage time_span createMeeting() { cout << "Meeting:" << endl; cout << "from: " << endl; cin >> meeting.fHour; cin >> meeting.fMinute; cout << "until: " << endl; cin >> meeting.uHour; cin >> meeting.uMinute; if (checkForAllowedNumber(meeting) == false) { cout << "Error" << endl; createMeeting(); } return meeting; } //Zufälligen Termin erstellen time_span createRandomMeeting() { meeting.fHour = rand() % 24; meeting.fMinute = rand() % 60; meeting.uHour = meeting.fHour + 1; meeting.uMinute = meeting.fMinute + 30; //90 Minuten pro Termin if (meeting.uHour >= 24 || meeting.uMinute >= 60) { createRandomMeeting(); } if (checkForAllowedNumber(meeting) == false) { createRandomMeeting(); } return meeting; } bool checkForAllowedNumber(time_span t) { if (t.fHour < 0 || t.fHour >= 24) { cout << "a" << endl; return false; } if (t.fMinute < 0 || t.fMinute >= 60) { cout << "b" << endl; return false; } if (t.uHour < 0) { cout << "c" << endl; return false; } if (t.fHour > t.uHour) { cout << "d" << endl; return false; } if (t.fHour == t.uHour && t.fMinute >= t.uMinute) { cout << "f" << endl; return false; } if (t.uMinute < 0) { cout << "e" << endl; return false; } return true; } }; class Calender :public Meeting { private: vector<time_span> schedule; string nameOfOwner; public: string get_name() { return nameOfOwner; } void set_name(string name) { nameOfOwner = name; } vector <time_span> get_schedule() { return schedule; } //Terminkalender anzeigen lassen void showSchedule() { cout << endl; for (int i = 0; i < schedule.size(); i++) { cout << setw(2) << setfill('0') << schedule[i].fHour << ":" << setw(2) << setfill('0') << schedule[i].fMinute << " - " << setw(2) << setfill('0') << schedule[i].uHour << ":" << setw(2) << setfill('0') << schedule[i].uMinute << endl; } cout << endl; } //Terminkalender eingeben, mit Abfrage der Termine vector <time_span> fillSchedule() { for (int i = 0; i < schedule.size(); i++) { schedule[i] = createMeeting(); } return schedule; } //Automatisch Terminkalender mit random Terminen erstellen vector <time_span> fillScheduleAutomatic(int numberOfMeetings) { for (int i = 0; i < numberOfMeetings; i++) { schedule[i] = createRandomMeeting(); } return schedule; } //Sortieren vector <time_span> sortSchedule() { sort(schedule.begin(), schedule.end(), [](const time_span& a, const time_span& b) { if (a.fHour != b.fHour) return a.fHour < b.uHour; else if (a.fMinute > b.fMinute) { return a.fHour > b.uHour; } return true; }); return schedule; } };
.h Datei
#ifndef KALENDER_H #define KALENDER_H using namespace std; struct time_span { int fHour; int fMinute; int uHour; int uMinute; }; //Basisklasse - Termin class Meeting { private: time_span meeting; public: time_span createMeeting(); time_span createMeeting(int, int, int, int); time_span createRandomMeeting(); bool checkForAllowedNumber(time_span); }; //Unterklasse - Terminkalender class Calender :public Meeting { private: vector <time_span> schedule; public: string get_name(); void set_name(string); vector <time_span> get_schedule(); void showSchedule(); vector <time_span> fillSchedule(); vector <time_span> fillScheduleAutomatic(int); vector <time_span> sortSchedule(); }; #endif
main.cpp
#include <iostream> #include <iomanip> #include <vector> #include <stdlib.h> #include <ctime> #include <algorithm> #include "Kalender.h" using namespace std; int main() { Calender a; a.set_name("Hans"); /... }
Kann mir jemand sagen, wie ich die Fehlermeldung loswerde?
-
@mute7 sagte in Problem mit Typneudefintion:
Kann mir jemand sagen, wie ich die Fehlermeldung loswerde?
Lösch die Definition von
time_span
,Meeting
undCalender
aus der .cpp Datei raus.
-
Ich dachte die Klasse gehört in die cpp Datei. Wie kann ich denn Defintion einer Klasse rausnehmen?
-
Du verwendest in der CPP-Datei die sogenannte Inline-Definition, d.h. du hast sowohl Deklaration der Klasse als auch Definition der Memberfunktionen in einem Code-Block.
Durch das Einbinden der Headerdatei (mittels
#include "Kalender.h"
) brauchst du nur die explizite Definitionen der Memberfunktionen (mittels Angabe des Klassennamens und Bereichsoperators::
) in der CPP-Datei:time_span Meeting::createMeeting(int fromHour, int fromMinute, int untilHour, int untilMinute) { // ... } // ...
Kurze Memberfunktionen (wie Getter/Setter) könntest du dann als Inline-Funktionen auch in der Headerdatei belassen (würde ich aber aus Konsistenzgründen ersteinmal von abraten).
PS: Und in der Headerdatei dann nur die anderen Headerdateien einbinden, welche auch wirklich dort benötigt werden (evtl. reichen auch Vorwärtsdeklarationen), nur in der CPP-Datei dann alle benötigten Headerdateien einbinden.
Und niemals
using namespace std;
in einer Headerdatei verwenden! Entweder explizitstd::
benutzen oder aber einzelneusing std::...
-Anweisungen (am besten in Zusammenspiel mit eigenem Namensbereich).
-
Ok, vielen Dank für die ausführliche Antwort, du hast mir sehr weitergeholfen und ich habe das Programm zum laufen bekommen
Kannst du vielleicht nochmal genauer erklären, warum using namespace std in Header Dateien so schlimm ist?
-
Weil durch die Einbindung der Headerdatei dann alle Namen aus dem
std
-Namensbereich in den globalen Namensbereich gebracht werden, d.h. wenn eine andere Datei diese Headerdatei einbindet und man einen eigenen (oder aus einer anderen Bibliothek verwendeten) Typ mit zufällig gleichen Namen wie einer derstd
-Namen verwendet (es gibt viele Namen, offiziell 'Identifier' genannt, dort!), dann kommt es zu einem Kompilierfehler wegen doppelten Namen - ähnlich wie dein "Problem mit Typneudefinition" hier ;- ).Edit: Oder wenn du z.B. selber einen Typ so nennst, wie ein Name aus dem
std
-Namensbereich: Ideone-Code...