von Objekt auf Objekt zugreifen



  • habe ich schon versucht:

    class Erste : public Root
    {
    

    Der debugger will aber nicht:

    error C2504: 'Root': Basisklasse undefiniert



  • hast du eventuell vergessen deine Root.h einzubinden? also da wo deine Root deklariert ist?



  • Oben hast du root kleingeschrieben und unten bei der Ableitung hast du es gross geschrieben. Ist das ein Kopierfehler?



  • Doch, hab ich. Hier mal etwas ausführlicher:

    WERoot.h:

    #ifndef _WEROOT
    #define _WEROOT
    
    #include "WERessourceManager.h"
    #include "WESceneManager.h"
    #include "WEWindowManager.h"
    
    namespace WheelEngine
    {
    	class Root
    	{
    	public:
    
    		void buh();
    
    		RessourceManager* mResourceManager;
    		SceneManager*     mSceneManager;
    		WindowManager*    mWindowManager;
    	};
    };
    
    #endif
    

    WEWindowManager.h:

    #ifndef _WEWINDOW
    #define _WEWINDOW
    
    #include "WERoot.h"
    
    namespace WheelEngine
    {
    	class WindowManager:public Root
    	{
    	public:
    		void CreateSceneWindow(char* szName, int iWidth, int iHeight, char* szTyp, bool bOwner, bool bFullscreen);
    	};
    };
    
    #endif
    

    WESceneManager.h:

    #ifndef _WESCENE
    #define _WESCENE
    
    #include "WERoot.h"
    
    namespace WheelEngine
    {
    	class SceneManager : public Root
    	{
    	public:
    		void AddMap() { }
    	};
    };
    
    #endif
    

    WEWindowManager.cpp

    #include "WE.h"
    
    namespace WheelEngine
    {
    	void WindowManager::CreateSceneWindow(char* szName, int iWidth, int iHeight, char* szTyp, bool bOwner, bool bFullscreen)
    	{
    		mSceneManager->AddMap();
    	}
    };
    

    Und zuletzt noch die WE.h:

    #ifndef _WE
    #define _WE
    
    #include <windows.h>
    #include <windowsx.h>
    #include <d3d9.h>
    #include <d3dx9.h>
    
    #include "WEClasses.h"
    #include "WERessourceManager.h"
    #include "WERoot.h"
    #include "WESceneManager.h"
    #include "WEWindowManager.h"
    
    #endif
    


  • Ich habe da mal was ausprobiert, nur mal alles verküürtzt in einer einzigen Datei:

    class A : public Root
    {
    public:
    	void Go() { };
    };
    
    class B : public Root
    {
    public:
    	void Stop() { };
    };
    
    class Root
    {
    public:
    	A* mA;
    	B* mB;
    };
    

    Jetzt ist das Problem ganz deutlich zu erkennen! Damit ich die zeiger setzen kann, müssen erst die Klassen A und B deklariert sein! Darum packe ich sie nach oben. Jetzt fehlt den beiden klassen aber die klasse Root! Wie mache ich das nun, das die beiden Klassen A und B auch die Klasse Root kennen?

    EDIT::::::

    Ich habs 🙂

    class A;
    class B;
    
    class Root
    {
    public:
    	A* mA;
    	B* mB;
    };
    
    class A : public Root
    {
    public:
    	void Go() { };
    };
    
    class B : public Root
    {
    public:
    	void Stop() { };
    };
    

    Ist dies der optimale weg, oder währe ein besserer zu empfehlen?



  • wenn du nur ein zeiger hast, musst du die klasse nicht definieren, nur deklarieren

    class A;
    class B;
    
    class Root
    {
    public:
        A* mA;
        B* mB;
    };
    
    class A : public Root
    {
    public:
        void Go() { };
    };
    
    class B : public Root
    {
    public:
        void Stop() { };
    };
    


  • mist schneller...

    das ist der normale weg und nennt sich "Forward Declaration".

    da du nur zeiger hast die immer gleich groß sind(4 Byte auf 32bit)
    braucht der compiler nur zu wissen, dass die "class A" existiert



  • Funktioniert aber irgentwie nicht wenn ich dann das hier machen will:

    class A : public Root
    {
    public:
    	void Go() { mB->Stop(); };
    };
    

    Mint der Debugger, das mB keine classe währe, also das eine klasse/union/struktur erwartet wird, und das B undefiniert ist!

    EDIT :::: Hehe! xD



  • Hmm 😞

    Kann man das dnn irgent wie anders machen, sondass der selbe zweck erfüllt wird?



  • Wenn du natürlich die Klasse benutzen willst (z.B. indem du auf Methoden zugreifst), muss sie schon vollständig definiert sein. Deshalb würde ich A::Go() nicht inline in der Klasse selber definieren, sondern ausserhalb in einer eigenen CPP-Datei. In diese Datei inkludierst du dann die Header der benötigten Klassen.



  • Ja bin ich auch grad drauf gekommen 🙂

    Nur habe ich jetzt nen anderes Problem, also es funktioniert inwandfrei! Aber in meiner maindatei benutze ich jetzt folgendes:

    Root* mRoot;
    A* mA;
    B* mB;
    
    mA->Go();
    

    Der debugger spuckt keine fehler aus, ich bekomme bloß einen Runtime fehler, irgentwas stimmt nicht it dem this zeiger 😕

    EDIT::::

    + this 0x00000000 WheelEngine::A * const
    + WheelEngine::Root {mA=??? mB=??? } WheelEngine::Root
    mA CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden
    mB CXX0030: Fehler: Ausdruck kann nicht ausgewertet werden



  • Du hast ja nur die Zeiger deklariert, ohne ihnen Speicher zuzuweisen.

    Root* mRoot = new Root(); // in die Klammern könnte man noch Konstruktorargumente schreiben
    

    Nicht vergessen, am Schluss wieder mit delete zu löschen!



  • Hab ich gemacht, fehler bleibt aber 😕





  • ...



  • Okay, diesen Topic st dann geschlossen, thx for help 🙂



  • Code-Walker schrieb:

    Ich vemute mal mir will niemand mehr helfen?

    Hast du einen Komplex? Du kannst nicht erwarten, dass du zwei Minuten nach deiner Frage gleich eine Antwort gestellt bekommst.

    Ich kann mir nicht vorstellen, dass das mit new nicht geht. Wenn, dann ist etwas an der Initialisierung fehlgeschlagen (wahrscheinlich im Konstruktor) oder du zerschreibst dir den Speicher noch nachträglich.

    Geh mal mit dem Debugger (im Debug-Modus) schrittweise durch, und überprüfe, von wo an kein gültiger Wert mehr besteht, bzw. ob überhaupt einmal eine korrekte Initialisierung stattfindet.

    Edit: Dir scheint auf spieleprogrammierer.de inzwischen geholfen worden zu sein. Das new muss man natürlich bei allen Zeigern ausführen...

    Und wie gesagt, vergiss kein delete , um den Speicher wieder freizugeben, wenn du ihn nicht mehr brauchst.



  • Nexus schrieb:

    Code-Walker schrieb:

    Ich vemute mal mir will niemand mehr helfen?

    Hast du einen Komplex? Du kannst nicht erwarten, dass du zwei Minuten nach deiner Frage gleich eine Antwort gestellt bekommst.

    Ich kann mir nicht vorstellen, dass das mit new nicht geht. Wenn, dann ist etwas an der Initialisierung fehlgeschlagen (wahrscheinlich im Konstruktor) oder du zerschreibst dir den Speicher noch nachträglich.

    Geh mal mit dem Debugger (im Debug-Modus) schrittweise durch, und überprüfe, von wo an kein gültiger Wert mehr besteht, bzw. ob überhaupt einmal eine korrekte Initialisierung stattfindet.

    Schau mal meinem Post auf sp.de an. Dort habe ich den Fehler gepostet.



  • drakon schrieb:

    Schau mal meinem Post auf sp.de an. Dort habe ich den Fehler gepostet.

    Ich habs gesehen 😉

    Naja, damit habe ich eigentlich nicht gerechnet... Etwas Mitdenken hätte ich schon erwartet, sodass man den Fehler nicht nur an einer Stelle behebt... 🙄



  • hab auf Spieleprogrammierer noch net nachgesehen, aber ich habs auch xD

    Root* mRoot = new Root();
    A* mA = new A();
    B* mB = new B();
    

    Außerdem haben Konstruktor und destuktor gefehlt, wobei der Konstruktur für den Run time error verantwortlich war! dankeschön 🙂


Anmelden zum Antworten