Zugriffsverletzung bei gegenseitiger Klassen-Abhängigkeit



  • Hallo zusammen, ich hab bei einem einfachen Klassenproblem mit Forward Declarations eine Zugriffsverletzung erhalten und bis jetzt nicht herausgefunden, woran es liegt. Ich hab dabei eine Klasse Map, die wiederum ein Array der Klasse Object enthält. Da dies nur mit Zeigern geht wegen der gegenseitigen Abhängigkeit habe ich eben ein Zeiger-Array von Object in Map deklariert.
    Ausserdem erhalte ich eine Warnung, wenn ich ein Objekt der Klasse Object (ich weiss die Namen sind nicht gut gewählt ;)) erzeuge; was bedeutet sie bzw. wie kann ich das beheben?

    #include <iostream>
    
    class Object;
    
    class Map
    {
    	public:
    	int Num;
    	Object *MapObjects[100];
    	void Init();
    };
    
    class Object
    {
    	int Type;
    	public:
    	void SetType(int T)	{Type = T;}     // hier Zugriffsverletzung
    	short int FirstFreeObj(Map NewMap);
    };
    
    short int Object::FirstFreeObj(Map NewMap)
    {
    	for (short int i = 0; i < 100; i++)
    	{
    		if (NewMap.MapObjects[i]->GetType() == 0)
    			return i;
    	}
    	return -1;
    }
    
    void Map::Init()
    {
    	for (short int i = 0; i < 100; i++)
    	{
    		MapObjects[i]->SetType(0);
    	}
    }
    
    int main()
    {
        Map M1;
    	M1.Num = 222;
    
    	Object O;        // Hier Warnung wegen unreferenzierter lokaler Variable O
    	M1.Init();
    }
    

    Es wird ja nichts ausserhalb des Object-Arrays geschrieben, und den Wert einer Klassenvariable festzulegen sollte eigentlich auch erlaubt sein... Ich kann jedoch in keiner Weise auf Type zugreifen... Wo liegt denn das Problem?



  • ich wundere mich zwar hauptsächlich darüber, was du mit deinem code anfangen willst, aber der fehler liegt darin, dass die Object s in MapObjects nicht existieren. du müsstest sie erst mit new konstruieren (oder keine zeiger verwenden und gleich auf dem stack arbeiten).

    imo passt FirstFreeObj besser in Map als in Object und als Init -methode verwendet man normalerweise den konstruktor, aber ohne zu wissen, was du genau mit dem code erreichen willst, ist es schwer, dir was besseres zu empfehlen 😉



  • Hehe, das mit dem Konstruktor ist mir bekannt, viele Funktionen (z.B. Init und FirstFreeObj) sollen ja auch noch ergänzt werden (z.B. Init soll nicht nur beim Erstellen einer Instanz aufgerufen werden - ein besserer Name dafür wäre "Reset":D). Zudem gings mir eher darum, den Fehler allgemein zu finden. Es tut mir leid wegen der Unübersichtlichkeit bzw. dem Mangel an Eleganz dieses Beispielcodes, ich bin mir bewusst, dass noch eine starke Optimierung möglich ist.

    Vielen Dank für deine Hilfe, queer_boy, mit new gehts jetzt. Früher habe ich es zwar auch mit new gemacht, aber ich hab schon einige Zeit nicht mehr objektorientiert programmiert und es deshalb vergessen. 🙂

    Das einzige, was ich jetzt noch nicht verstehe, ist folgende Warnung:
    warning C4101: 'O': Unreferenzierte lokale Variable
    Das scheint ein ähnliches Problem zu sein, denn wenn ich nach dem Erstellen eine Funktion aufrufe oder wenn ich einen Zeiger auf die Klasse erstelle, erscheint die Warnung nicht. Ich nehme an, der Compiler will sicher sein, dass eine Instanz richtig initialisiert wird oder eine Klasse überhaupt gebraucht wird, oder sehe ich das falsch (wobei ich nicht ganz verstehe, ob es einen Unterschied macht, eine leere Memberfunktion aufzurufen anstatt gar nichts zu tun)? Ich kann zwar damit leben, da ich eigentlich immer etwas mit der Klasse anstelle, der Grund für die Warnung hätte mich jedoch trotzdem interessiert 😉

    int main()
    {
    	Object O;				// Hier wird die Warnung angezeigt
    
    	Object *P;			   // so kommt die Warnung nicht
    	P = new Object();
    
    	Object Q;				// so merkwürdigerweise auch nicht
    	Q.SetType(2);
    }
    


  • die warnung bedeutet nur, dass du ein objekt erstellst, und es nirgendwo verwendest.



  • Okay, vielen Dank!


Anmelden zum Antworten