Objekt1 mit Pointer auf Objekt2, mit Pointer auf Objekt1 -> Fehler?



  • Hi!

    ich habe einen seltsamen fehler und ich finde keine lösung...

    es geht um 2 Klassen. die jeweils einen Pointer zur anderen Klasse haben, weil sie beide gewissen informationen benötigen. daher übergebe ich den beiden klasse einen pointer zur jeweils anderen klasse. ich hab ehrlich gesagt nichtmal eine ahnung wieso das ein problem sein sollte... aber irgendwas stimmt nicht 😕

    Ich bekomme mehrere Fehler. die sehen alle aus wie dieser hier:

    ...hexapod_siso\control.h(17): error C2061: Syntaxfehler: Bezeichner 'Picking' (Zeile 17)
    1>...hexapod_siso\control.h(42): error C2143: Syntaxfehler: Es fehlt ';' vor '*' (Zeile 22)
    1>...hexapod_siso\control.h(42): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    1>...hexapod_siso\control.h(42): error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt.
    

    Das zielt auf zeile: 17 und die dazugehörige Zeile 22.
    weitere fehler von diesem Muster zielen auf Zeile 49 und 54...

    und hier sind die headerfiles beider Klassen:

    #ifndef CONTROL_H_CL90
    #define CONTROL_H_CL90
    
    #include "init_configuration.h"   // Alle header sind mit includewächter gesichert, daher kein problem hier
    #include "Hexapod.h"
    #include "view_light.h"
    #include "picking.h"
    
    class Control
    {
    	public:
    		Control();
    		~Control();
    		void	set_hexa(Hexapod*	hexa);
    		void	set_view(View_Light* view);
    		void	set_pick(Picking*	pick);
    
    	private:
    		Hexapod*		m_hexa;
    		View_Light*		m_view;
    		Picking*		m_pick;
    };
    
    #endif
    
    #ifndef PICKING_H_CL90
    #define PICKING_H_CL90
    
    #include "init_configuration.h"
    #include "hexapod.h"
    #include "control.h"
    #include "view_light.h"
    
    using namespace std;
    
    class Picking
    {
    	friend class Control;
    
    	public:
    		Picking(Hexapod* hexa, Control* ctrl, View_Light* view, LPDIRECT3DTEXTURE9* texture, int enable);
    		~Picking();
    
    	private:
    		Hexapod*			m_hexa;
    		Control*			m_ctrl;
    		View_Light*			m_view;
    
    };
    
    #endif
    

    ist es nun verboten unter klassen sich gegenseitig pointer zu geben? gibts da vlt eine schönere variante? oder hab ich woanders einen fehler?


  • Mod

    control.h bindet picking.h ein und umgekehrt. Kreisschluss.

    Lösung: Für Zeiger auf eine Klasse reicht eine forward-Deklaration.

    Alternative: Gesamtdesign überdenken, mich dünkt du hast übles vor, wenn ich mir den Code so ansehe.



  • dafür ja die include wächter....
    Die Cpp files die zu den h files gehören brauchen notwendige deklarationen anderer objekte um compilen zu können. da ist doch kein kreisschluss.
    #ifndef BLA
    sichert einmaliges includieren ab.

    ja. ich habe großes vor. bzw bin grade im umbau.
    das sind zwei stark reduzierte objekte aus einer 3D Grafikengine

    was gäbe es denn für sinvolle Aufbaustrukturen?
    Derzeit habe ich eine renderframe schleife die in key-events bestimmte funktionen aus meinen 5 Objekten anwendet. (die objekte agieren viel untereinander)

    Hexapod, Control, Picking, View_Light und DXDevice.
    ist es denn unüblich das z.b. Control intern soeinen aufruf macht:

    m_hexa->get_leg(m_pick->get_select(0))->set_angle(0.0f, 0.0f, 0.0f, 0.0f);
    

    er nimmt das ausgewählte bein von hexapod und setzt die winkel alle auf 0. welches bein ausgewählt ist, erfährt er von picking.


  • Mod

    cl90 schrieb:

    dafür ja die include wächter....

    Nein, Includeguards sind für was anderes da. Die verhindern keine Probleme durch zirkuläre Abhängigkeiten (die sind ein echter Fehler), sondern Probleme durch mehrfaches Include (die sind kein echter Fehler, da man nicht immer wissen kann, was andere Header indirekt einbinden).



  • tatsächlich... danke vielmals 🙂
    ich habe das jetzt nocheinmal angepasst.

    aber es ist ziemlich unschön das ich da so drauf achten muss... gibt es da intelligentere lösungen?



  • cl90 schrieb:

    gibt es da intelligentere lösungen?

    Die intelligenteste Lösung: Design ändern. Normalerweise sind solche zirkulären Abhängigkeiten ein klares Zeichen für fehlerhaftes Design (selbst wenn man sie auflösen kann).

    Die zweite Lösung: Code ändern, so dass das Include nicht notwendig ist. Eine forward-Deklaration ist ausreichend, wenn
    * Der Typ nur als Rückgabetyp angegeben wird
    * der Typ nur als Pointer (inklusive Template-Argument in Smart Pointern) oder Referenz verwendet wird


Anmelden zum Antworten