Ich komme mit der Headerdatei nicht weiter
-
Ich arbeite gerade mit dem Buch "C++ Einsteigerseminar" von Alexander Niemann und bin jetzt im 5. Kapitel angelangt da gehts um Objektoriente Programmierung. Genauer gesagt es geht um Klassen. Ich habe aus dem Buch die Headerdatei abgetippt und als "CRechteck.h" abgespeichert. Das Hauptprogramm als "CRechteck.cpp". Nun bekomme ich vom Kompiler (Borland 5.5) die Meldung: "Include Datei zu tief verschachtelt". Was heisst das?
Im Buch steht nichts drüber wie was genau gemacht werden soll. Ich denke mal im selben Ordner wo sich der "CRechteck.cpp" befindet.
-
Ich denke mal du solltest Code posten.
-
Denke du hast sowas gemacht
Header1.h includiert Header2.h der wieder Header1.h includiert
Kurt
-
Dichter und Denker schrieb:
Ich denke mal du solltest Code posten.
Ok hier ein Beispiel:
Das Hauptprogramm
#include "CRechteck.h" #include <iostream.h> int main() { CRechteck einRechteck; int iSeiteA, iSeiteB; //Daten des Rechtecks vom Benutzer holen cout << "Laenge der ersten Seite: "; cin >> iSeiteA; cout << "Laenge der zweiten Seite: "; cin >> iSeiteB; // Seitenlänge des Rechteck-Objekts stzen einRechteck.SetzeSeiten(iSeiteA, iSeiteB); //Einige Informationen ausgeben cout << "Flaeche: " << einRechteck.BerechneFlaeche() << endl; if (einRechteck.IstQuadrat()) cout << "Das Rechteck ist ein Quadrat." << endl; else cout << "Das Rechteck ist kein Quadrat." << endl; };Die Include Datei:
#include "CRechteck.h" void CRechteck::SetzeSeiten(unsigned int iLaengeSeiteA, unsigned int iLaengeSeiteB) { iSeiteA = iLaengeSeiteA; iSeiteB = iLaengeSeiteB; }; bool CRechteck::IstQuadrat() { return (iSeiteA == iSeiteB); }; int CRechteck::BerechneFlaeche() { return iSeiteA * iSeiteB; };
-
Rechteck.h includiert Rechteck.h.
lass #include "Rechteck.h" in Rechteck.h weg.Kurt
Edit: Sehe gerade dein Header ist ja eine Implementations-File
-
Oder benutz Include-Guards
-
#include <iostream.h>lol
-
ZuK schrieb:
Rechteck.h includiert Rechteck.h.
lass #include "Rechteck.h" in Rechteck.h weg.Kurt
Edit: Sehe gerade dein Header ist ja eine Implementations-File
geht leider auch in die Hose.
Ich krieg da immer die Meldung: Qualifizierter 'CRechteck' ist kein Name einer Klasse oder einer Struktur" usw.
-
Du hast da was mit headern und implementationen durcheinendergebracht.
Am besten postest du alle drei files.
Kurt
-
ZuK schrieb:
Du hast da was mit headern und implementationen durcheinendergebracht.
Am besten postest du alle drei files.
KurtKeine Ahnung welche das ist.
-
Irgend wo musst du noch ein File habe das irgend so aussieht und das sollte
CRechteck .h heissen. In diesem File solltest du solltest auch includeguards verwenden#ifndef CRECHTECK_INCLUDED #define CRECHTECK_INCLUDED class CRechteck { public: void SetzeSeiten(unsigned int iLaengeSeiteA, unsigned int iLaengeSeiteB); bool IstQuadrat(); .... }; #endifDas File das du Include Datei genannt hast
solltest du so wie es ist als CRechteck.cpp abspeichern.
Dann sollte es funktionieren
Kurt
-
Ahh ja, ich hab da im Buch mal wieder nicht aufgepasst. Das hat noch gefehlt:
class CRechteck { public: void SetzeSeiten(unsigned int, unsigned int); bool IstQuadrat(); int BerechneFlaeche(); protected: int iSeiteA, iSeiteB; };Das habe ich als "CRechteck.h" abgespeichert.
Das hier als "CRechteck.cpp"
#include "CRechteck.h" void CRechteck::SetzeSeiten(unsigned int iLaengeSeiteA, unsigned int iLaengeSeiteB) { iSeiteA = iLaengeSeiteA; iSeiteB = iLaengeSeiteB; }; bool CRechteck::IstQuadrat() { return (iSeiteA == iSeiteB); }; int CRechteck::BerechneFlaeche() { return iSeiteA * iSeiteB; };und das hier als "RechteckDemo.cpp".
#include <iostream.h> #include "CRechteck.h" int main() { CRechteck einRechteck; int iSeiteA, iSeiteB; //Daten des Rechtecks vom Benutzer holen cout << "Laenge der ersten Seite: "; cin >> iSeiteA; cout << "Laenge der zweiten Seite: "; cin >> iSeiteB; // Seitenlänge des Rechteck-Objekts stzen einRechteck.SetzeSeiten(iSeiteA, iSeiteB); //Einige Informationen ausgeben cout << "Flaeche: " << einRechteck.BerechneFlaeche() << endl; if (einRechteck.IstQuadrat()) cout << "Das Rechteck ist ein Quadrat." << endl; else cout << "Das Rechteck ist kein Quadrat." << endl; };Aber ich komme da immer noch nicht voran, der Kompiler meckert wieder:
Erro: Unresolved external 'CRechteck::SetzeSeiten(unsigned int, unsigned int)' referenced from C:\C++\RECHTECKDEMO.OBJ
und so weiter. Ich habe erst CRechteck.cpp kompiliert und dann RechteckDemo.cpp und krieg diese Meldung. Ich muss ehrlich sagen, Klassen programmieren ist echt ein hartes Stück Brot!
-
Du mußt die beiden dabei entstandenen Objektdateien noch zusammenlinken.
-
Braunstein schrieb:
Du mußt die beiden dabei entstandenen Objektdateien noch zusammenlinken.
Im Buch steht was von Makefile erstellen, dass sieht dann so aus:
# Pfade zu Include - Datien und Libs in Variablen speichern INCLUDE = D:\Programme\Borland\BCC55\Include LIB = D:\Programme\Borland\BCC55\Lib CPP = bcc32 # Abhängikeiten von "RechteckDemo.exe" RechteckDemo.exe: RechteckDemo.obj CRechteck.obj $(CPP) -I$(INCLUDE) -L$(LIB) RechteckDemo.obj CRechteck.obj -o$@ # Allgemeine Abhängigkeit von Objektdateien .cpp.obj: $(CPP) -I$(INCLUDE) -L$(LIB) -c $< # Target "clean" clean: del *.obj\ del *.exe\ del *.tdsSieht irgendwie umständlich aus findet ihr nicht? Aber so hat es diesmal geklappt mit dem kompilieren. Allein mit "bcc32 " gehts nicht. Wie man die beiden Dateien sonst manuell verlinken muss, da hab ich keine Ahnung, wird in diesem Buch nicht erklärt, ausser das mit dem Makefile. Naja, Hauptsache es hat diesmal geklappt.
Danke
A.N
-
AlexNeumann schrieb:
# Pfade zu Include - Datien und Libs in Variablen speichern INCLUDE = D:\Programme\Borland\BCC55\Include LIB = D:\Programme\Borland\BCC55\Lib CPP = bcc32 # Abhängikeiten von "RechteckDemo.exe" RechteckDemo.exe: RechteckDemo.obj CRechteck.obj $(CPP) -I$(INCLUDE) -L$(LIB) RechteckDemo.obj CRechteck.obj -o$@ # Allgemeine Abhängigkeit von Objektdateien .cpp.obj: $(CPP) -I$(INCLUDE) -L$(LIB) -c $< # Target "clean" clean: del *.obj\ del *.exe\ del *.tdsMeiner Meinung nach hat das obige Makefile einige Fehler und Unzulänglichkeiten.
RechteckDemo.exe: RechteckDemo.obj CRechteck.obj $(CPP) -I$(INCLUDE) -L$(LIB) RechteckDemo.obj CRechteck.obj -o$@Dieses Target erstellt RechteckDemo.exe. Zum Erzeugen der .exe sind keine Include-dateien(pfade) notwendig es wird in diesem Fall ja nur gelinkt.
Es genügt alsoRechteckDemo.exe: RechteckDemo.obj CRechteck.obj $(CPP) -L$(LIB) RechteckDemo.obj CRechteck.obj -o$@die Folgende Regel erklärt wie aus einer .cpp datei eine .obj Datei erstellt wird.
.cpp.obj: $(CPP) -I$(INCLUDE) -L$(LIB) -c $<Der -c switch weist den Compiler an nur zu kompilieren. Also den Linker nicht zu bemühen. Warum sollte man dann library pfade und zu linkende libraries übergeben? Besser wäre also
.cpp.obj: $(CPP) -I$(INCLUDE) -c $<Ausserdem werden dem compiler üblicherweise noch zusätzliche Flags übergeben wie zb warning levels oder präprozessor defines und gewünschte optimierungs level usw.
Es sollte also noch ein Symbol für Compilerflags definiert werden.
zBCPPFLAGS=-DNDEBUGDie Regel sollte dann so aussehen
.cpp.obj: $(CPP) $(CPPFLAGS) -I$(INCLUDE) -c $<Dieses Makefile hat noch einen grossen Nachteil. Die Headerdateien sind nirgends in den Abhängigkeiten angegeben. Bei Änderungen nur in den Headern werden die zugehörigen Objektdateien nicht neu erzeugt das kann zu schwer zu findenden Fehlern führen. Ich würde das obige Makefile also folgendermassen umschreiben.
# Pfade zu Include - Datien und Libs in Variablen speichern INCLUDE = D:\Programme\Borland\BCC55\Include LIB = D:\Programme\Borland\BCC55\Lib CPP = bcc32 # compilerflags CPPFLAGS= # Abhängikeiten von "RechteckDemo.exe" RechteckDemo.exe: RechteckDemo.obj CRechteck.obj $(CPP) -L$(LIB) RechteckDemo.obj CRechteck.obj -o$@ # Abhängigkeit von Objektdateien RechteckDemo.obj: RechteckDemo.cpp CRechteck.h $(CPP) -I$(INCLUDE) $(CPPFLAGS) -c RechteckDemo.cpp -o RechteckDemo.obj CRechteck.obj: CRechteck.cpp CRechteck.h $(CPP) -I$(INCLUDE) $(CPPFLAGS) -c CRechteck.cpp -o CRechteck.obj # Target "clean" clean: del *.obj\ del *.exe\ del *.tdsBTW. make zeigt sich ziemlich zickig wenn bei den Regeln die Zeile mit einem Leerzeichen beginnt. Es will ein Tab. Die tabs werden aber scheinbar von der Forumsoftware in Leerzeichen umgewandelt. Ebenso speichern manche Editoren tabs als Leerzeichen. Diese sind dann zur Erzeugung eines Makefiles nicht geeignet.
AlexNeumann schrieb:
Sieht irgendwie umständlich aus findet ihr nicht? Aber so hat es diesmal geklappt mit dem kompilieren. Allein mit "bcc32 " gehts nicht.
Folgendes Kommando sollte die .exe auch erstellen
bcc32 -ID:\Programme\Borland\BCC55\Include -LD:\Programme\Borland\BCC55\Lib RechteckDemo.cpp CRechteck.cpp -o RechteckDemo.exeKurt
-
@ZuK bist du Informatiker? Was hast du so alles auf'm Kasten?
-
Nein. Habe nur 20 jahre Scheisse gebaut. Langsam wirds besser.

Kurt
-
ZuK schrieb:
Nein. Habe nur 20 jahre Scheisse gebaut. Langsam wirds besser.

Kurtlol, wieso scheisse gebaut?