Problem mit zyklischer Abhaengigkeit beim Klassendesign.
-
Hallo liebe C++ Experten.
Ich habe ein Problem beim Design meiner Klassen und hoffe, dass mir vielleicht jemand auf die Spruenge helfen kann.
Es existiert eine Basisklasse 'Device' von der die Klasse 'Controller' erbt. Jedes Device hat protected member, wie die Hardware-Adresse und vor allem einen Pointer auf einen Controller, der fuer dieses Device zustaendig ist. Nun habe ich das Problem der zyklischen Abhaengigkeit, da ja 'Controller.h' in der Klasse Device eingebunden sein muss, um als Member den Typ Controller zur Verfuegung zu haben. Controller erbt allerdings von Device, was zu dem Zeitpunkt des erstmaligen Inkludierens ja noch garnicht bekannt ist. Gibt es eine Loesung fuer das Problem?
Hier nochmal der Quelltext:
Device.h:
#ifndef __DEVICE__ #define __DEVICE__ using namespace std; #include "CAENVMEtypes.h" /// Definitions of types defined by hardware library. #include "Controller.h" class Device { protected: unsigned int mBaseaddress; ///< base address of Device CVAddressModifier mAddressModifier; ///< default address modifier CVDataWidth mDataWidth; ///< default data width VMEController* mController; ///< pointer to controller public: Device(unsigned int baseaddress = 0x0); Device(Controller* controller, unsigned int baseaddress = 0x0); ~Device(); /** * Reads data from device internal address with default data width. * @param address address offset to read from */ virtual long read_addr(unsigned int address); /** * Writes data to device internal address with default data width. * @param address address offset to read from */ virtual long write_addr(unsigned int address, long data); }; #endifController.h:
#ifndef __CONTROLLER__ #define __CONTROLLER__ #ifndef __CAENVMELIB__ #define __CAENVMELIB__ #include "CAENVMElib.h" // hardware library used by Controller #endif #include "Device.h" using namespace std; class Controller: public Device { private: int mControllerHandle; ///Handle to access the Controller needed by library. public: Controller(short baseaddress = 0); ~Controller(); long read_addr(unsigned int baseaddress, unsigned int address, CVAddressModifier addressmodifier, CVDataWidth datawidth); long write_addr(unsigned int baseaddress, unsigned int address, CVAddressModifier addressmodifier, CVDataWidth datawidth, long data);Die Methode read_addr(unsigned int address) des Device sieht dann so aus:
long read_addr(unsigned int address) { mController->read_addr(mBaseaddress, address, mAddressModifier, mDataWidth); return 0; }Das jeweilige Device ruft also seinen zugeordneten Controller auf und teilt der hardwarenahen Controller-Read-Methode seine BaseAddress sowie die zu lesende Registeraddresse 'address' und die Defaultwerte fuer AdressModifier und DataWidth mit.
Die Idee dahinter war, dass auch der Controller ein Device ist (der Controller-Pointer mController wird im Konstruktor einfach auf this gesetzt), sodass man auch beim Controller mit der abstrahierten read und write Methode zum Lesen und Schreiben der Register arbeiten kann...
Waere wirklich toll, wenn mir jemand helfen koennte.
-
Hallo,
ich hab's nur kurz überlesen... aber wahrscheinlich hilft Dir das.
nîmm in Device.h das include von Controler.h raus und mach statt dessen eine Forward deklaration:
class Controller;im dazugehörenden Device.cpp musst Du aber Controler.h includen.
Herzliche Grüsse
WalterPS. nimm das "using namespace std;" aus den *.h Files raus, das gehört da definitiv nicht hin.
-
Vielen, vielen Dank! Das hat schon geholfen! Die forward declaration hatte ich auch schon probiert, allerdings bin ich nicht auf die Idee gekommen #include "Controller.h" rauszunehmen
.Nochmals tausend Dank!
"using namespace std" habe ich nun in die source datei gepackt oder spricht da etwas dagegen?
-
Hallo,
"using namespace std" habe ich nun in die source datei gepackt oder spricht da etwas dagegen?
ich mache es auch so... Puristen werden uns steinigen

Herzliche Grüsse
Walter
-
Und nochmals: Scheibe C-Code in .h- oder .c-Dateien und C++-Code in .hpp-, .hh-, .cpp- oder in .cc-Dateien!

-
Hallo,
ich habe *.hpp und *.hh ausser in diesem Forum und Boost noch nirgends gesehen. Weder CodeProject, CodeGuru noch irgend eine mir bekannte komerzielle Library verwendet eine dieser Extensions für Header Files.
Ich glaube der Entscheid für *.h als Header Extension auch für C++ ist quasi Basisdemokratisch schon längst gefällt

Herzliche Grüsse
Walter
-
EOutOfResources schrieb:
Und nochmals: Scheibe C-Code in .h- oder .c-Dateien und C++-Code in .hpp-, .hh-, .cpp- oder in .cc-Dateien!

Die Endung h ist durchaus auch in C++ üblich, nicht aber die Endung "c".
-
weicher schrieb:
ich habe *.hpp und *.hh ausser in diesem Forum und Boost noch nirgends gesehen.
Echt? Es stimmt zwar, dass viele C++-Bibliotheken .h benutzen, aber meinem Eindruck nach sind das häufig etwas ältere.
Jedenfalls spricht absolut nichts dagegen, für eigene Projekte .hpp zu nehmen, erst recht keine "quasi basisdemokratische Entscheidung". Ich würde .hpp sogar empfehlen, um deutlicher zu machen, dass es sich um C++-Code handelt.
-
Nexus schrieb:
weicher schrieb:
ich habe *.hpp und *.hh ausser in diesem Forum und Boost noch nirgends gesehen.
Echt? Es stimmt zwar, dass viele C++-Bibliotheken .h benutzen, aber meinem Eindruck nach sind das häufig etwas ältere.
Jedenfalls spricht absolut nichts dagegen, für eigene Projekte .hpp zu nehmen, erst recht keine "quasi basisdemokratische Entscheidung". Ich würde .hpp sogar empfehlen, um deutlicher zu machen, dass es sich um C++-Code handelt.
Ich benutze nur noch .cpp und .hpp .