Fehlersuche LNK2005+LNK1169
-
Hallo allerseits!
Ich bin Programmier- Newbee und habe mich an nachfolgender Klasse erprobt. Beim Linkvorgang wurden mir die folgenden Fehlermeldungen ausgegeben:RASSEN_KLASSEN.obj : error LNK2005: "class _BASISWERTE ObjektA" (?ObjektA@@3V_BASISWERTE@@A) bereits in BASISWERTE.obj definiert Debug/DD.exe : fatal error LNK1169: Ein oder mehrere mehrfach definierte Symbole gefunden
Ich suche nun schon seit fast ner Stunde nach dem Problem, komme aber leider mit meinen bisherigen Kenntnissen nicht weiter.
Aus der C++Hilfe wurde ich bisher ebenfalls nicht schlau.
Für Tips in Sachen Programmierstil bin ich ebenfalls immer aufgeschlossenQuellcode:
// BASISWERTE.h: Schnittstelle für die Klasse BASISWERTE. #ifndef _BASISWERTE_ #define _BASISWERTE_ class _BASISWERTE { private: int Lebensenergie; public: _BASISWERTE(); ~_BASISWERTE(); int Staerke, Konstitution, Geschicklichkeit, Schnelligkeit, Intelligenz, Weisheit, Charisma; int Zufallszahl; BerechneAttributeGesamt(int ST, int KO, int GE, int SCH, int IN, int WE, int CH); int RueckgabeST(); int RueckgabeKO(); int RueckgabeGE(); int RueckgabeSCH(); int RueckgabeIN(); int RueckgabeWE(); int RueckgabeCH(); BerechneLebensenergie (int AnzahlWuerfel, int ArtWuerfel, int KO); RueckgabeLebensenergie(); } ObjektA; #endif // BASISWERTE.CPP #include "BASISWERTE.h" #include <iostream> #include <stdlib.h> #include <time.h> using namespace std; _BASISWERTE::_BASISWERTE() { } _BASISWERTE::~_BASISWERTE() { // Speicher freigeben !!! } _BASISWERTE::BerechneAttributeGesamt(int ST, int KO, int GE, int SCH, int IN, int WE, int CH) { //Hauptschleife int eingabe; for (int i=40; i>0;) // FOR-Schleife { char auswahl; cout << "Weitere" << i << "Punkte können verteilt werden!!!\n" "Bitte Attribut waehlen, auf das Punkte verteilt werden sollen:\n" "(S)taerke, (K)onstitution, (G)eschicklichkeit, Sch(N)elligkeit,\n" "(I)ntelligenz, (W)eisheit, (C)harisma, (A)bbruch Programm!\nIhre Eingabe:\t"; cin >> auswahl; switch (auswahl) //SWITCH-Schleife { case 'S': case 's': { cout << "\nWie viele Punkte auf Staerke?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } ST = ST + eingabe; cout << "Staerke wurde auf " << ST << "erhoeht!"; break; } case 'K': case 'k': { cout << "\nWie viele Punkte auf Konstitution?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } KO = KO + eingabe; cout << "Konstitution wurde auf " << KO << "erhoeht!"; break; } case 'G': case 'g': { cout << "\nWie viele Punkte auf Geschicklichkeit?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } GE = GE + eingabe; cout << "Geschicklichkeit wurde auf " << GE << "erhoeht!"; break; } case 'N': case 'n': { cout << "\nWie viele Punkte auf Schnelligkeit?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } SCH = SCH + eingabe; cout << "Schnelligkeit wurde auf " << SCH << "erhoeht!"; break; } case 'I': case 'i': { cout << "\nWie viele Punkte auf Intelligenz?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } IN = IN + eingabe; cout << "Intelligenz wurde auf " << IN << "erhoeht!"; break; } case 'W': case 'w': { cout << "\nWie viele Punkte auf Weisheit?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } WE = WE + eingabe; cout << "Weisheit wurde auf " << WE << "erhoeht!"; break; } case 'C': case 'c': { cout << "\nWie viele Punkte auf Charisma?\t"; cin >> eingabe; while ((i-eingabe) < 0) { cout << "Zu hoher Wert!!!\nErneute Eingabe:\n"; cin >> eingabe; } CH = CH + eingabe; cout << "Charisma wurde auf " << CH << "erhoeht!"; break; } case 'A': case 'a': { cout << "\nProgrammabbruch!\n"; exit (0); } default: cout << "\nAbbruch des Programmes!\n"; break; } // SWITCH-Schleife ENDE } // FOR- Schleife ENDE i=(i-eingabe); ObjektA.Staerke = ST; ObjektA.Konstitution = KO; ObjektA.Geschicklichkeit = GE; ObjektA.Schnelligkeit = SCH; ObjektA.Intelligenz = IN; ObjektA.Weisheit = WE; ObjektA.Charisma = CH; } //Hauptschleife ENDE int RueckgabeST() { return ObjektA.Staerke; } int RueckgabeKO() { return ObjektA.Konstitution; } int RueckgabeGE() { return ObjektA.Geschicklichkeit; } int RueckgabeSCH() { return ObjektA.Schnelligkeit; } int RueckgabeIN() { return ObjektA.Intelligenz; } int RueckgabeWE() { return ObjektA.Weisheit; } int RueckgabeCH() { return ObjektA.Charisma; } _BASISWERTE::BerechneLebensenergie (int AnzahlWuerfel, int ArtWuerfel, int KO_NEU) { ObjektA.Zufallszahl = 0; srand (time (NULL)); for (int i = 0; i <= (AnzahlWuerfel-1); i++) ObjektA.Zufallszahl += rand()%ArtWuerfel+1; ObjektA.Zufallszahl *= (KO_NEU / 10); } _BASISWERTE::RueckgabeLebensenergie() { return ObjektA.Zufallszahl; }
-
Lies mal ein Buch/Tutorial über OOP. So wie oben geht das nicht.
-
Hi,
Du hast da ziemlich viel, sehr seltsam gelöst.
z.B. Warum hast du das so gemacht?
i=(i-eingabe); ObjektA.Staerke = ST; ObjektA.Konstitution = KO; ObjektA.Geschicklichkeit = GE; ObjektA.Schnelligkeit = SCH; ObjektA.Intelligenz = IN; ObjektA.Weisheit = WE; ObjektA.Charisma = CH;
Und nicht so: i=(i-eingabe); Staerke = ST; Konstitution = KO; Geschicklichkeit = GE; Schnelligkeit = SCH; Intelligenz = IN; Weisheit = WE; Charisma = CH;
Wie du siehst kann man das AObject weglassen. (Das solltest du aber wissen wenn du mit Klassen hantierst
So dann das nächste "Problem":
int RueckgabeST() { return ObjektA.Staerke; } int RueckgabeKO() { return ObjektA.Konstitution; } int RueckgabeGE() { return ObjektA.Geschicklichkeit; } int RueckgabeSCH() { return ObjektA.Schnelligkeit; } int RueckgabeIN() { return ObjektA.Intelligenz; } int RueckgabeWE() { return ObjektA.Weisheit; } int RueckgabeCH() { return ObjektA.Charisma; }
Das sollte eher so sein:
int _BASISWERTE::RueckgabeST() { return Staerke; } int _BASISWERTE::RueckgabeKO() { return Konstitution; } int _BASISWERTE::RueckgabeGE() { return Geschicklichkeit; } int _BASISWERTE::RueckgabeSCH() { return Schnelligkeit; } int _BASISWERTE::RueckgabeIN() { return Intelligenz; } int _BASISWERTE::RueckgabeWE() { return Weisheit; } int _BASISWERTE::RueckgabeCH() { return Charisma; }
Das sind doch Methoden aus deiner Klasse _BASISWERTE ! Also musst du sie aus so deklarieren (das sie noch der Klasse angehören )
Und nun:
BerechneLebensenergie (int AnzahlWuerfel, int ArtWuerfel, int KO); RueckgabeLebensenergie(); _BASISWERTE::BerechneLebensenergie (int AnzahlWuerfel, int ArtWuerfel, int KO_NEU) { ObjektA.Zufallszahl = 0; srand (time (NULL)); for (int i = 0; i <= (AnzahlWuerfel-1); i++) Zufallszahl += rand()%ArtWuerfel+1; Zufallszahl *= (KO_NEU / 10); } _BASISWERTE::RueckgabeLebensenergie() { return Zufallszahl; }
Hallo? Haben wir was vergessen ????
Ah ja stimmt, den Returntyp, ja wo isser denn?Naja also alles in allem solltest du dich mal wirklich noch ein wenig mit C++ Büchern auseinander setzen oder ein gutes Tutorial lesen: [url=http://tutorial.schornboeck.net/inhalt.htm]
http://tutorial.schornboeck.net/inhalt.htm
[/url]MfG
-
ich lös mal dein eigentliches problem
// BASISWERTE.h: Schnittstelle für die Klasse BASISWERTE. #ifndef _BASISWERTE_ #define _BASISWERTE_ class _BASISWERTE { public: _BASISWERTE(); ~_BASISWERTE(); ... ... }; //ObjektA; das muss weg //stattdessen extern _BASISWERTE ObjektA; #endif
// BASISWERTE.CPP #include "BASISWERTE.h" #include <iostream> #include <stdlib.h> #include <time.h> using namespace std; //und hier noch _BASISWERTE ObjektA;
-
Erstmal danke für die Hilfe!
@Sovok:
Stimmt, "extern" und anschließende Einbindung des Objektes in die CPP bin ich gestern Nacht nicht mehr drauf gekommen.@eViLiSSiMo:
Die Definion/ Initialisierung der Variablen "Staerke", "Konstitution", usw. ohne Einbindung von "ObjektA" habe ich mehrfach versucht (eben erst nochmal aufgrund Deiner Tips). Leider bekomme ich dann jedesmal die Fehlermeldung, dass es sich bei den Variablen "Staerke", usw. um "nichtdeklarierte Bezeichner" handelt. Da ich den Fehler nicht lokalisieren konnte, wollte ich das Problem durch die Einbindung von "ObjektA" lösen.
Sind die Variablen nicht durch Deklaration in der Headerdatei und das Setzen von "public" genügend bezeichnet!?Die granze Leserei in Büchern und Tutorials bringt übringens für einen richtigen Programmieranfänger nichts, wenn man sich nicht auch mal außerhalb des dort Besprochenen selbst einige Aufgaben stellt. Habe mittlerweile 3 Bücher und 2 Tutorials durch, aber bei der Umsetzung denkt man dann teilweise schiefer als eigentlich nötig und kann die Fehler auch unter Zuhilfenahme der Bücher nicht lokalisieren.
-
Neo schrieb:
Die Definion/ Initialisierung der Variablen "Staerke", "Konstitution", usw. ohne Einbindung von "ObjektA" habe ich mehrfach versucht (eben erst nochmal aufgrund Deiner Tips). Leider bekomme ich dann jedesmal die Fehlermeldung, dass es sich bei den Variablen "Staerke", usw. um "nichtdeklarierte Bezeichner" handelt.
Dann zeig doch einfach mal eine deiner Funktionen, die so einen Fehler verursacht.
Neo schrieb:
Sind die Variablen nicht durch Deklaration in der Headerdatei und das Setzen von "public" genügend bezeichnet!?
Member einfach so public zu machen, ist nicht Sinn und Zweck von OOP.
Ausserdem solltest du auf const-correctness achten. ZB sollten Funktionen, die keine Member verändern, const definiert werden. Bsp
int _BASISWERTE::RueckgabeST() const { return Staerke; }
Und benutze bitte ordentliche Klassennamen, _BASISWERTE hat den Charakter eines Compilermakros.
-
OK danke für Deine Tips, habe das mal so umgesetzt!
Ich habe den Fehler nun übrigens gefunden...
Wenn ich der Memberfunktion ( Funktion() )außerhalb der Klasse nicht die Klasse ( Klasse::Funktion() ) vorweg stelle, ist es kein Wunder, dass die Variablen als "nicht bezeichnet" gelten. <sich an die Stirn klatscht>
also so:
[cpp]int **_BASISWERTE::**RueckgabeST() const
{
return Staerke;
}[/cpp]und nicht so:
int RueckgabeST() { return Staerke; }
Ich dachte zuerst, dass der Fehler darin liegt, dass ich die Variablen "Staerke" usw. in der ".h" als private bezeichnet habe und habe sie deshalb in den public-Bereich verschoben und dann "ObjektA" eingefügt, da es immer noch nicht geklappt hatte. Habe den Fehler also an der falschen Stelle vermutet und dadurch das Prog umsomehr verbaut.
Natürlich klappt es nun auch mit den Variablen im private-Bereich, wo ich sie auch eigentlich haben wollte.
Hinsichtlich der Ursprungsversion, die ich hier nicht gepostet habe, hätte ich den Funkitionsnamen also nur "BASISWERTE::" vorhängen müssen und die Funktionen hinsichtlich dem Schutz vor Veränderung mit const bezeichnen sollen.
Danke für Eure zahlreichen Tips, solangsam verstehe ich das Prinzip der Klassen immer besser