dynamisches 2 dimensionales Array von Objecten initialisieren ?
-
Ich bin einbisschen verwirrt, weil ich kein Beispiel im Internet gefunden habe und immer sowas gesagt wird wie:
"When creating dynamic arrays with your own object types, you cannot overload the constructor. The ISO standard forbids this, and you must initialize the values on the objects later. All objects allocated into arrays must utilize the default constructor."class GridNode { int graphcol; int x; int y; GridNode(){} GridNode(int px, int py) : x(px), y(py), graphcol(_WHITE){} }; class MyRect { int x; int y; int width; int height; GridNode** data; MyRect(int px,int py,int pwidth,int pheight, Bitmap^ bmp) : x(px), y(py), width(pwidth), height(pheight) { data = new GridNode*[width]; for(int i = 0; i < width; i++) { data[i] = new GridNode[height]; for(int j = 0; j < height; j++) data[i][j] = GridNode(px+i,py+j); } } ~MyRect() { for(int i = 0; i < width; i++) { delete[] data[i]; } delete[] data[width]; } };Wäre der Code richtig ? Oder müsste ich statt
data[i][j] = GridNode(px+i,py+j);das hier machen
data[i][j] = new GridNode; data[i][j] = GridNode(px+i,py+j);?
Oder müsste ich die ganz anders Initialisieren ? (Ja ich weiß das man auch Vector verwenden könnte, will aber trotzdem wissen wie die richtige "low level Variante" aussehen würde)
-
candybomberz schrieb:
Ja ich weiß das man auch Vector verwenden könnte, will aber trotzdem wissen wie die richtige "low level Variante" aussehen würde
Die Low-Level-Variante?
class MyRect { std::vector<GridNode> data; std::size_t w; MyRect(std::size_t w, std::size_t h) : data(w*h), w(w) {} GridNode& at(std::size_t x, std::size_t y) { return data[x+w*y]; } };Low-leveliger geht es nicht mehr ausser man schreibt seine eigene fixed_array-Klasse. C-Arrays und allgemein ungekapselte new/delete verwendet in modernem C++ keiner mehr.
Was du machst, ist kein 2-dimensionales Array, das ist ein cacheunfreundliches Jagged Array. So etwas macht man einfach nicht und wenn dann kann man auch gleich vector<vector<T>> nehmen.
-
unabh. davon, was sinnvoll ist, hier die Erklärung:
indata = new GridNode*[width];werden width Pointer auf GridNode angelegt, der Pointer auf den ersten Pointer wird data zugewiesen
indata[i] = new GridNode[height];werden height Objekte vom Typ GridNode mit ihrem Default-Konstruktor erzeugt, der Pointer auf das erste Objekt wird data[i] zugewiesen
indata[i][j] = GridNode(px+i,py+j);soll dem GridNode Objekt data[i][j] mittels op= ein neuer Wert zugewiesen werden, und zwar ein temp. Objekt, das mit dem Konstruktor GridNode(int,int) erzeugt wurde
das Problem besteht nun aber darin, daß data als GridNode** deklariert wurde, und der Compiler nicht weiß, wie er data[i][j] interpretieren soll, da width und height variabel sind
-
dd++ schrieb:
das Problem besteht nun aber darin, daß data als GridNode** deklariert wurde, und der Compiler nicht weiß, wie er data[i][j] interpretieren soll, da width und height variabel sind
Doch, das weiss er sehr wohl.
data[i] gibt GridNode* zurück, wendet man darauf ein [j] an erhält man GridNode&. Dass dabei auf ein temp. Objekt zugewiesen wird ist auch in Ordnung.Das einzige Problem, das ich am Code sehe, sind die privaten Konstruktoren von GridNode.
PS@candybomberz: Du kannst das "p" bei den Parametern weglassen, das sieht etwas unbeholfen aus. Ausserdem kann der Name _WHITE zu Problemen führen (wie viele Namen, die mit "_" beginnen).
-
jaggy schrieb:
Was du machst, ist kein 2-dimensionales Array, das ist ein cacheunfreundliches Jagged Array. So etwas macht man einfach nicht und wenn dann kann man auch gleich vector<vector<T>> nehmen.
Ok danke, auch besonders für den Beispiel Code, aber missverstehe ich dich oder ist vector<vector<T>> auch ein cacheunfreundliches Jagged Array ?
-
candybomberz schrieb:
ist vector<vector<T>> auch ein cacacheunfreundliches Jagged Array ?
Ja.
-
jaggy schrieb:
Du kannst das "p" bei den Parametern weglassen
Aber dann ist der Name der Parameter doch dergleiche wie bei den Membern ? Das würde doch nicht gehen oder ? und ich habe _ bei den Globals Verwendet um zusammenstöße mit Locals und Membern zu vermeiden
jaggy schrieb:
candybomberz schrieb:
ist vector<vector<T>> auch ein cacacheunfreundliches Jagged Array ?
Ja.
Was wäre eine bessere Alternative?
-
...
-
candybomberz schrieb:
Ich bin einbisschen verwirrt, weil ich kein Beispiel im Internet gefunden habe und immer sowas gesagt wird wie:
"When creating dynamic arrays with your own object types, you cannot overload the constructor. The ISO standard forbids this, and you must initialize the values on the objects later. All objects allocated into arrays must utilize the default constructor."Mal abgesehen davon, dass das englische Zitat nicht von hoher fachlicher Kompetenz des Zitierten zeugt:
Was verwirrt Dich jetzt? Wofür kein Beispiel gefunden?
Dafür, das es nicht geht, oder dafür, das es geht?
Und welche Schlüsse ziehst Du daraus "kein Beispiel im Internet gefunden" zu haben?Übrigens: es geht durchaus mit
braced-init-lists.Ich weiss nur nicht, inwieweit das für Dich von Belang ist, da Dein Code kein reines C++ ist.
jaggy schrieb:
Das einzige Problem, das ich am Code sehe, sind die privaten Konstruktoren von GridNode.
Und der Fehlerhafte Destruktor von MyRect.
-
...
-
Ich hab mal im zusammenhand mit Optimierung, Vektorisierung gelesen, hat die Klasse Vector irgentwas damit zu tun?
Das mein Destruktor Fehlerhaft war hab ich auch beim Ausprobieren nacher gemerkt, und die Initialisierung wäre auch redundant, da ich einfach die durch new erzeugten Objekte verändern kann,
und nur weil mein Code eine C++/Cli Sache enthält, die nichtmal verwendet wird, heißt das nicht das meine Frage in das zugehörige Unterforum gehört :p
-
std::vector und Vektorisieren haben nicht viel miteinander zu tun. Vektorisierung ist ein hybscher optimierungstrick den man selbst(oder manchmal der compiler auch automatisch) anwenden kann, um die Performance des Programms zu verbessern. Dabei werden mehrere Berechnungen gleichzeitig parallel durchgeführt (SIMD). Da sich SIMD sehr gut mit dem abstrakten Konzept von Vektoren in der Mathematik verträgt, nennt man das vektorisierung. (AFAIK)
-
otze schrieb:
Da sich SIMD sehr gut mit dem abstrakten Konzept von Vektoren in der Mathematik verträgt, nennt man das vektorisierung. (AFAIK)
Nö, man nennt es Vektorisierung da man viele Operationen mit Skalaren durch weniger Operationen mit Vektoren ersetzt.
Anders gesagt: das Programm (Source-Code) arbeitet mit Skalaren, das übersetzte Programm aber mit Vektoren. Das Programm wird also "vektorisiert".
-
Danke nochmal an alle Antworten, die Frage hat sich geklärt (aus diesem Beitrag :D)