Dreiecksbeziehung
-
Hi,
also ich hab gar keine Forwarddeklarationen, da ich nicht wüsste an welchen Stellen ich diese platzieren könnte. Und mit Nachdenken komme ich auch nicht weiter. Irgendwie übersteigt das mein Vorstellvermögen.
-
Irgendwie fehlt mir eine präzise Problembeschreibung. Was genau ist denn das Problem mit den Vorwärtsdeklarationen?
// Vorwärtsdeklaration Klasse1 struct Klasse1; //Definition Klasse2 struct Klasse2 { // Vorwärsdeklaration Klasse2::foo void foo(Klasse1& x); }; // Definition Klasse1 struct Klasse1 { // Definition Klasse1::foo void foo(Klasse2& x) { x.foo(*this); } }; // Definition Klasse2::foo void Klasse2::foo(Klasse1& x) { x.foo(*this); // Schöne Endlosrekursion }(Ungetestet)
-
Es gibt halt 3 Klassen
-
NaKlasse schrieb:
Es gibt halt 3 Klassen
Ja. Sollte ja mit ein wenig Nachdenken abstrahierbar und auf drei Klassen erweiterbar sein.
-
Du musst schauen, dass du in den Headerdateien (für die Deklaration) bei den problematischen Klassen nur Zeiger verwendest. In den Headerdateien inkludierst du die Header der anderen Klassen _nicht_, sondern verwendest eine Forwärtsdeklaration. In den Implementationsdateien kannst du problemlos die Header der anderen Klassen einbinden.
Ich würde dir des weiteren empfehlen, Guards (#ifndef __DATEI_H__ #define ...) zu verwenden um Mehrfachdeklarationen zu vermeiden.
Grüße Martin
-
Ist es nicht unschön in der Implentation sowas zu inkludieren?
Das wollte ich daher eigentlich vermeiden
-
NaKlasse schrieb:
Ist es nicht unschön in der Implentation sowas zu inkludieren?
Das wollte ich daher eigentlich vermeiden
Was empfindest du als unschön? In der Implementierungsdatei andere Headerdateien einzubinden? Aber genau das machst du doch auch bei der Standardbibliothek, wenn du z.B. Strings verwenden möchtest.
Grüße Martin
-
@NaKlasse:
Schreib mal was deine 3 Klassen so tun/wie die so aussehen. Dann kann man sich vielleicht was drunter vorstellen.Ansonsten, was nicht ganz unüblich ist, ist ein eigenes Headerfile zu machen, wo einfach alle fwd. declarations drinnen sind:
// mylib/fwd.hpp: #ifndef MYLIB_FWD_HPP_INCLUDED #define MYLIB_FWD_HPP_INCLUDED class List; class Message; class Interface; template <class T> class Foo; template <class T, class U> void Bar(T*, U*); //... #endif // MYLIB_FWD_HPP_INCLUDEDDas inkludierst du einfach wo du es brauchst.
Brauchst du dann z.B. in "Interface.hpp" den kompletten Typ "Message", musst du natürlich in "Interface.hpp" vorher "Message.hpp" includieren - eine fwd. declaration reicht dann ja nichtmehr.
Und wenn du selbst damit nichtmehr auskommst ist es sehr wahrscheinlich dass du etwas machen willst was sowieso unmöglich ist (so wie z.B. "ein A hat ein B als member und ein B hat ein A als member" -> kann nicht gehen)
-
lucky_tux schrieb:
NaKlasse schrieb:
Ist es nicht unschön in der Implentation sowas zu inkludieren?
Das wollte ich daher eigentlich vermeiden
Was empfindest du als unschön? In der Implementierungsdatei andere Headerdateien einzubinden? Aber genau das machst du doch auch bei der Standardbibliothek, wenn du z.B. Strings verwenden möchtest.
Grüße Martin
Ich habe bisher immer vermieden, in der Implentierungsdatei eine andere Header, als die der Klasse zu inkludieren.
//### Foobar.cpp #include <string> class Foobar { }; //### Foobar.h #include "Foobar.h" //#include <string> // <-- Ist das nicht unschön, das HIER zu inkludieren!?------
hustbaer schrieb:
@NaKlasse:
Schreib mal was deine 3 Klassen so tun/wie die so aussehen. Dann kann man sich vielleicht was drunter vorstellen.Ansonsten, was nicht ganz unüblich ist, ist ein eigenes Headerfile zu machen, wo einfach alle fwd. declarations drinnen sind:
// mylib/fwd.hpp: #ifndef MYLIB_FWD_HPP_INCLUDED #define MYLIB_FWD_HPP_INCLUDED class List; class Message; class Interface; template <class T> class Foo; template <class T, class U> void Bar(T*, U*); //... #endif // MYLIB_FWD_HPP_INCLUDEDDas inkludierst du einfach wo du es brauchst.
Brauchst du dann z.B. in "Interface.hpp" den kompletten Typ "Message", musst du natürlich in "Interface.hpp" vorher "Message.hpp" includieren - eine fwd. declaration reicht dann ja nichtmehr.
Und wenn du selbst damit nichtmehr auskommst ist es sehr wahrscheinlich dass du etwas machen willst was sowieso unmöglich ist (so wie z.B. "ein A hat ein B als member und ein B hat ein A als member" -> kann nicht gehen)
Meine Klasse sieht in etwa so aus, kann gerade leider nicht an den PC wo die Daten liegen:
//### List.h #include "Interface.h" class List { typedef Interface... }; //### Message.h #include "List.h" class Message { List MeineListe; }; //### Interface.h // Hier brauche ich jetzt einen typedef der Message enthält, // inkludiere ich hier aber Message.h kriege ich Fehlermeldungen. // Das ganze scheint eine endlos Inkludierung zu werden // Bereitet mir jedenfalls eine menge Kopfschmerzen... :D class Interface { // ... };Würde mich über Hilfe sehr freuen. Danke

Gruß
-
Ich fahr mit der Regel des: "inkludiere was du benutzt" besser. Dank den Include Guards passiert ja nichts im Falle von zu häufigem Inkludieren.
Auszerdem sieht es für mich komisch aus, wenn du string in der .h inkludierst, aber da gar nicht nutzt. Dadurch wird string auch automatisch in alle cpps inkludiert, in die du den header inkludierst... obwohl du das vielleicht gar nicht brauchst da.
meine bescheidene Anfängermeinung.
Lösung wurde mehrmals gepostet: Forwarddeklarationen und Pointer.
-
NaKlasse schrieb:
[...]
Ich habe bisher immer vermieden, in der Implentierungsdatei eine andere Header, als die der Klasse zu inkludieren.
[...]Das ist meiner Meinung nach aber der beste weg. Alles was in den Header muss da rein den rest in die "Implementierungsdatei"
So habe ich das jedenfalls bis jetzt immer gemacht.