Hallo,
ich bin bei C++ absoluter Anfänger, also bitte nicht hauen für die dumme
Frage...
Zur Übung soll ich ein Programm "Autovermietung" programmieren. Es gibt
eine Klasse "Kunde" und eine Klasse "Fahrzeug", jeweils als doppelt
verkettete Liste. Die Objekte der Klasse "Kunde" enthalten Zeiger vom
Typ "Fahrzeug", der auf das gemietete Fahrzeug zeigt, wenn der Kunde
eines gemietet hat. Die Objekte der Klasse "Fahrzeug" enthalten Zeiger
vom Typ "Kunde", der auf den Kunden zeigt, der das Fahrzeug gemietet
hat.
Ich habe die Klassendefinitionen und das Hauptprogramm in eine einzige
Datei geschrieben. Der Compiler ist Dev C++ "Bloodshed", weil der
Lehrstuhl den empfohlen hat.
Beim Kompilieren kriege ich Fehlermeldungen: Wenn die Kunden-Klasse vor
der Fahrzeug-Klasse in der Datei kommt, kann der Compiler nichts mit dem
Zeiger auf das Fahrzeug-Objekt anfangen, wenn die Fahrzeug-Klasse vor
der Kunden-Klasse kommt, kann der Compiler nichts mit dem Zeiger auf das
Kunden-Objekt anfangen.
Wenn ich erst Kunden-Klasse und dann Fahrzeug-Klasse definiere, und am
Anfang der Datei, vor der Kunden-Klasse einfach deklariere:
class Fahrzeug{};
dann kriege ich eine Fehlermeldung "redefinition of class Fahrzeug".
Dürfen Klassen in C++ einfach nicht gegenseitig aufeinander zeigen? Oder
gibt es einen Trick, wie man sowas kompilieren kann?
Danke, Philipp
Markus_Bauer schrieb:> Ich habe die Klassendefinitionen und das Hauptprogramm in eine einzige> Datei geschrieben. Der Compiler ist Dev C++ "Bloodshed", weil der> Lehrstuhl den empfohlen hat.
das ist eine IDE, der Compiler wird wahrscheinlich der GCC sein.
> Dürfen Klassen in C++ einfach nicht gegenseitig aufeinander zeigen? Oder> gibt es einen Trick, wie man sowas kompilieren kann?
dürfen sie. Genau, wie man bei Funktionen zwischen Deklaration und
Definition unterscheidet, kann man das auch bei Klassen:
1
classFahrzeug();
ohne {} wäre eine Deklaration (auch manchmal "forward declaration"
genannt). Die reicht, damit Du den Typen im Zusammenhang mit Zeigern und
Referenzen verwenden kannst.
mfg Torsten
p.s.: Auch wenn ihr es in der Schule lernt: verkette Listen schreibt
keiner von Hand.
Sorry, ich habe Unsinn geschrieben.
Der Compiler meckert erst, wenn ich in der Kunden-Klasse eine
public-Methode der Fahrzeugklasse aufrufen will. Z.B. wenn ich in einer
Methode der Kunden-Klasse eine publi-Methode der Fahrzeugklasse aufrufen
will. Konkret will ich Kundendaten ausgeben und dabei den Typ des
gemieteten Fahrezeugs ausgeben. Ich habe also einen Zeiger auf das
gemietete Fahrzeug und möchte dann eine public-Methode des Fahrzeugs
aufrufen, z.B mit
gemietet->getTyp()
"gemietet" ist der Name des Zeigers, "getTyp" der Name der
public-Methode des Fahrzeug-Objekts. Sie soll einen string zurückgeben.
Ich kriege leider den Compiler-Fehler "getTyp has not been declared".
Wie kann ich die Methode deklariere, ohne dass ich die
"redefinition"-Fehlermeldung kriege?
Danke
Tom schrieb:> Um einen Zeiger auf etwas zu deklarieren, muss der Compiler nur wissen,> dass es etwas gibt (forward declaration): class Fahrzeug;
Das funktioniert, danke. Sieht so aus:
<c>
class Fahrzeug;
class Kunde
{
private:
Fahrzeug* gemietet;
....
public:
void ausgabe()
{cout << gemietet->getTyp();} //hier kommt der Compilerfehler
...
};
class Fahrzeug
{
private:
Kunde* vermietet;
string typ;
...
public:
string getTyp()
{return typ;}
....};
</c>
Wahrscheinlich muss ich die Methode "getTyp" vor der Klasse "Kunde"
irgendwie deklarieren, oder?
Vielen Dank euch allen
Markus_Bauer schrieb:> Tom schrieb:>> Um einen Zeiger auf etwas zu deklarieren, muss der Compiler nur wissen,>> dass es etwas gibt (forward declaration): class Fahrzeug;>> Das funktioniert, danke. Sieht so aus:>> <c>> class Fahrzeug;>> class Kunde> {> private:> Fahrzeug* gemietet;> ....> public:> void ausgabe()> {cout << gemietet->getTyp();} //hier kommt der Compilerfehler> ...> };>> class Fahrzeug> {> private:> Kunde* vermietet;> string typ;> ...> public:> string getTyp()> {return typ;}> ....};> </c>>> Wahrscheinlich muss ich die Methode "getTyp" vor der Klasse "Kunde"> irgendwie deklarieren, oder?
Ja, indem du die Klasse definierst, bevor du getTyp aufrufst. Wie schon
gesagt wurde, wäre es sinnvoller, das sauber auf mehrere Dateien
aufzutrennen und nicht alles in eine reinzuwurschteln.
Wie werden Objekte deiner Klassen erzeugt und wieder freigegeben?
Wenn du so weit bist, dass das ganze compiliert, könnte das mit dem
Freigeben zu einem Problem werden.
Weil, wenn die gegenseitig aufeinander zeigen, und du gibst ein Objekt
frei, dann hat das andere Zeiger, die ins Leere zeigen. Wenn du nicht
aufpasst. Ist nicht schlimm, du darfst diese Zeiger dann aber nicht mehr
dereferenzieren (das Objekt, auf das sie mal gezeigt haben, benutzen).
Sebastian schrieb:> Wie werden Objekte deiner Klassen erzeugt und wieder freigegeben?
Würde mich nicht wundern, wenn selbst der Prof dabei Fehler macht ;-)
guest schrieb:> Torsten R. schrieb:>> Würde mich nicht wundern, wenn selbst der Prof dabei Fehler macht ;-)>> Mich würde eher wundern, wenn er keine macht :)
Und mich würde wundern wenn ein Prof auf die Idee käme das ein Kunde
nicht nur ein Auto mieten kann :-))
Moin,
Anstatt irgend welche circularen Abhängigkeiten zu erzeugen, solltest du
lieber eine Verwaltungsklasse erstellen, welche Autos und Miete zusammen
bringt. Dann braucht das Auto selber nicht zu wissen, an wenn es gerade
vermietet ist und der Mieter muss es sich auch nicht merken ;)
Bin ja positiv überrascht, das der dev-c++ mal wieder weiter entwickelt
wird. Wobei 2016 ja offensichtlich nichts gemacht wurde.
Markus_Bauer schrieb:> Zur Übung soll ich ein Programm "Autovermietung" programmieren. Es gibt> eine Klasse "Kunde" und eine Klasse "Fahrzeug", jeweils als doppelt> verkettete Liste. Die Objekte der Klasse "Kunde" enthalten Zeiger vom> Typ "Fahrzeug", der auf das gemietete Fahrzeug zeigt, wenn der Kunde> eines gemietet hat. Die Objekte der Klasse "Fahrzeug" enthalten Zeiger> vom Typ "Kunde", der auf den Kunden zeigt, der das Fahrzeug gemietet> hat.
Im realen Leben fehlt hier eine Klasse "Vertrag", die jeweils eine
Referenz (oder meinetwegen einen Pointer) auf den Kunden und auf das FZ
beinhaltet. Schließlich kann ein Firmenkunde gleichzeitig mehrere
Fahrzeuge mieten, und irgendwo sollten wohl auch die Vertragsdetails
(Mietbeginn und -ende, Preis, inkludierte Kilometer, ...) gespeichert
werden.
Letztlich können wir Dir bei Deinen Problemen sicher besser helfen, wenn
Du uns Deinen Quellcode zeigst. ;-)
>mehrer Klassen, die gegenseitig aufeinander zeigen
Wirf an einer Schule eine Scheibe ein und brülle: "Wer war das?". Du
wirst sehen: mehrere Klassen, die gegenseitig aufeinander zeigen
:)
MfG Paul
Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.
Wichtige Regeln - erst lesen, dann posten!
Groß- und Kleinschreibung verwenden
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang