Meine erste Frage ist, wie sieht das intern aus? Was ich vermute:
Wenn Foo eine Klasse ist, dann ist Array ein Zeiger auf ein Array von Pointern von foo-Objekten vector<Foo*> v //c++
Wenn Foo eine Struktur ist, dann ist Array ein Zeiger auf ein Array von Foo-Objekten. vector<Foo> v //c++
Ist ein dynamisches Array in D zusammenhängend im Speicher wie in C ++?
Ein dynamisches D-Array sieht so aus:
%Vor% Doing new T[size]
führt im Grunde folgendes aus:
Also, ja, die Erinnerung an die Elemente ist zusammenhängend wie in C ++. Der Rest Ihrer Frage bezieht sich auf das, was T ist, und Sie haben recht, was Sie dachten:
Wenn Foo
eine Klasse ist, bedeutet das, dass jeder Verweis auf Foo
wie ein Zeiger funktioniert, also ist es wie Foo*
array in C ++ - T.sizeof
, wenn T eine Klasse ist, ist immer gleich void*.sizeof
*, die Objekte funktionieren per Referenz. Wenn es eine Struktur ist, ist alles in-Place, wie vector<Foo>
in C ++.
Fun fact mit Strukturen btw: sie sind nicht unbedingt im Array wegen der Ausrichtungsprobleme gepackt. Berücksichtigen Sie Folgendes:
%Vor% Foo.sizeof
könnte 6 sein ... aber es ist eigentlich 8, weil die Uint an einer 4-Byte-Grenze ausgerichtet wird, was nach s
zwei Bytes der Auffüllung verursacht. Wenn Sie align(1)
zum Feld "uint" hinzufügen, überschreiben Sie dies und setzen i
direkt neben s
in den Speicher. Da es sich jedoch um Arrays handelt, möchten Sie, dass Foo[]
elements / noch eine eigene Ausrichtung haben ... Foo.sizeof == 8
noch so, dass Foo[2]
eine Größe von 16 hat. Der innere align(1)
hat das Padding einfach an das Ende der Struktur verschoben, es wurde jedoch nicht vollständig für die Fälle von Arrays entfernt.
Wenn Sie ein Foo[]
wollen, das ohne Padding zwischen Elementen gepackt ist, möchten Sie auch align(1)
zu außerhalb der Struktur hinzufügen: align(1) struct Foo { /* ... */ }
. Dann Foo.sizeof == 6 und es gibt keine Auffüllung im Array.
new MyClass
schreiben, gibt es auch eine Möglichkeit, dies zu tun: __traits(classInstanceSize, Foo)
. Ссылка Aber D macht Klassen als Referenz, weil es einfacher ist, bei Vorhandensein von Vererbung gesund zu bleiben. Wie auch immer, ich ging wahrscheinlich detaillierter ins Detail, als Sie eigentlich wollten / brauchten, aber kurz gesagt, Sie haben recht, was mit Foo
passiert und ein dynamisches D-Array ist ähnlich aufgebaut wie ein C ++ Vektor. Der größte Unterschied zwischen den beiden ist, dass ein C ++ - Vektor mit dem assign-Operator kopiert werden kann, es ist ein Werttyp. Ein D-Array wird immer nur geschnitten - die Länge und der Zeiger (erinnern Sie sich an das erste Layout in diesem Beitrag) wird kopiert, aber der Inhalt nicht. Sie müssen die Daten explizit in D mit array.dup
oder foo[] = bar[]
kopieren.
Weiterführende Literatur:
foo[] = bar[]
-Stück, "Array-Eigenschaften" hat dup
und viel mehr drin) Ссылка (spricht über das Array selbst gegenüber dem Slice, den Sie bearbeiten, und erklärt einige Interna über Dynamic Array-Speicherverwaltung)
Ссылка (Sie können Informationen über die Strukturausrichtung dort finden)
array
selbst ist eine Struktur mit einem size_t length
und einem Foo* ptr
Dies ist in Ссылка beschrieben (suche nach Arrays)
Und ja, der Speicher befindet sich im zusammenhängenden Speicher.