Mehrdimensionales Array von eigener Klasse initialisieren



  • Hallo,

    ich will meine eigene Klasse TFeld als 2 dimensionales array initialisieren.

    TFeld **Spielfeld = new TFeld*[999][999];
    
    for(int i = 0; i <= 999; i++)
    	for(int j = 0; i <= 999; i++)
    	{
    		Spielfeld[i][j] = new TFeld(i,j,0);
    	}
    
    Error: Ein Wert vom Typ ""TFeld *(*)[999]"" kann nicht zum Initialisieren einer Entiät vom Typ ""TFeld**"" verwendet werden.
    

    könnt ihr mir helfen was ich da ändern muss?



  • Deine Variable hat einen doppelten Pointer und du willst einen dreifachen Initialisieren. Das muss schon rechts und links das gleiche stehen. Also

    TFeld ***Spielfeld = ...
    

  • Mod

    Spielfeld ist ein Zeiger auf ein Zeiger auf ein TFeld . new TFeld*[999][999] liefert dir einen Zeiger auf 999 Zeiger auf TFeld. Klar geht das nicht zusammen.

    Da du dich mit Pointern icht wirklich auszukennen scheinst (ist auch schwer und ich hoffe meine eigene Aufschlüsselung von dem was new TFeld*[999][999] gibt ist richtig - bei so viel Indirektion kommt man leicht durcheinander): Warum benutzt du nicht std::vector, oder Boost (Multi-)Array oder eine eigene kleine Spielfeldklasse? Praktisch alles ist besser, als zigfache Pointerindirektion. Dafür gibt es auch einen Namen: Drei Sterne Programmierer (das ist eine negative Bezeichnung!)



  • Vergiss was ich oben geschrieben habe. Das war nicht ganz richtig. Es sollte vielleicht besser so aussehen:

    TFeld* Spielfeld[999][999];
    
    	for(int i=0; i<999; ++i)
    		for(int j=0; j<999; ++j)
    			Spielfeld[i][j] = new TFeld(i, j, 0);
    

    Schönen Gruß

    Max


  • Mod

    @Max3000: Syntaktisch zwar richtig, aber manche Systeme haben recht strenge Beschränkungen was die Stackgröße angeht. 1 Million Pointer sind schon ganz schön heftig und sollten vielleicht doch (wie vom Threadersteller geplant) dynamisch angefordert werden.



  • SeppJ schrieb:

    @Max3000: Syntaktisch zwar richtig, aber manche Systeme haben recht strenge Beschränkungen was die Stackgröße angeht. 1 Million Pointer sind schon ganz schön heftig und sollten vielleicht doch (wie vom Threadersteller geplant) dynamisch angefordert werden.

    Tatsache. Kompilieren klappt zwar, aber beim ausführen kommt ein Laufzeitfehler mit stack overflow.



  • Nebenbei ist bei 999 Elementen pro Dimension der höchste gültige Index 998, jedoch nicht 999, wie du in deiner Schleife annimmst.



  • Ich stimme SeppJ zu, dass boost::multi_array hier eine deutlich sinnvollere Lösung wäre. Der Vollständigkeit halber aber hier die Syntax für den flachen Zeiger:

    TFeld *(*Spielfeld)[1000] = new TFeld*[1000][1000];
    

    Übrigens: Unter der Annahme, dass du den Borland-Compiler benutzt, sähe ich an deiner Stelle davon ab, ein Präfix für meine Klassen zu benutzen, das bereits von der mitgelieferten Grafikbibliothek beansprucht wird.


  • Mod

    Wobei ich seldon jedoch nicht zustimme ist, dass boost::multi_array die beste Lösung wäre. Ich habe da negativste Performanceerfahrung mit gemacht. Das kann wohl einfach zu viel und bringt zu viel Overhead mit, der hier anscheinend nicht gebraucht würde. Meine Empfehlung für ein Spielfeld mit statischen Dimensionen: Ein normaler vector mit 999x999 Länge und einem Wrapper drum, der Zugriffe auf (x,y) auf x+999*y umlenkt. Geht ab wie nix.

    Außerdem: So wie es aussieht, ist hier keine Polymorphie im Spiel. Daher würde ich in so einem Vector (oder egal welchem Container) konkrete Objekte speichern, keine Pointer.



  • SeppJ schrieb:

    Meine Empfehlung für ein Spielfeld mit statischen Dimensionen: Ein normaler vector mit 999x999 Länge und einem Wrapper drum, der Zugriffe auf (x,y) auf x+999*y umlenkt. Geht ab wie nix.

    In diese Kerbe haue ich auch. Und dann würde ich vielleicht gleich 1024x999 nehmen und 2,5% Space gegen noch eine Hauch von Speed umtauschen. Man hat ja einen Wrapper.


Anmelden zum Antworten