Einzelnen Beitrag anzeigen

Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Array mit verschiedenen Records

  Alt 4. Jul 2007, 15:02
Hi,
so geht das nicht. Ein Array ist eine sehr einfache Art von Speicherstruktur, die nur dazu bestimmt ist einfach (und schnell) auf eine bestimmte (feste) Menge von gleichen Daten zugreifen zu können. Legst Du ein Array an, so wird einfach die Größe eines Elements mit der Anzahl der Elemente multitpliziert und der entsprechend Wert wird als Menge an Speicher alloziert. Anders gesagt, hast Du ein Array, dass aus 10 Integer Werten besteht (egal ob dynamisch oder statisch), dann wird hier einfach 10 * 4 Byte (sizeOf(Integer) = 4) alloziert. Nun merkt sich Delphi noch die Adresse des ersten Elements im Array. Möchtest Du nun auf das 7te Element zugreifen, so weiß Delphi hier, dass es einfach an 4 Byte an der Adresse (StartadresseDesArrays + 7 * 4) zugreifen muss.
Das ist gerade der Vorteil eines solchen Array, die Daten liegen alle am Stück im Speicher, da greifen einerseits Caching-Techniken recht gut und er wahlfreie Zugriff (Element an Stelle x) ist möglich.

Unterschiedliche Typen können eben genau diese Art von Zugriff nicht garantieren, das gilt auch für gleich große Elemente (z.B. Cardinal und Integer). Schließlich sind das unterschiedliche Typen, die könnten also (theoretisch) auch die Größe unabhängig voneinander ändern!

Was Du benutzen kannst ist immer etwas gleiches. Da gibt es schon mal die Möglichkeit, dass Du ein Array von Zeigern verwaltest und die speicherst. Die Records kannst Du dann (wenn Du die dyn. erzeugen willst) mit new erzeugen und die Adresse im Array speichern. Sind die Records statisch, musst Du darauf achten, dass die adresse nur lokal gültig ist, alles was Du in einer Methode als lokale Parameter deklarierst landet nur auf dem Stack und wird beim verlassen der Methode dort auch abgeräumt. Globale Variablen, Instanz- und Klassenvariablen, Instanzen von Klassen und eben mittels new erzeugte Typen unterliegen nicht der Einschränkung (Daten landen im Heap).

Das Problem dass Du beim arbeiten mit Zeigern hast (kannst hier auch auf eine TList statt einem Record of Pointerzurückgreifen) ist, dass Du nicht weißt was für einen Typ sich hinter dem Zeiger verbirgt. Der speichert nur eine Adresse, was sich an der Adresse befindet musst Du schon selbst wissen. Hier ist also die Frage, wie Du das ganze dann erkennen möchtest, eine Möglichkeit ist natürlich ein Record aus dem Typ und dem Zeiger.

Ansonsten kannst Du das ganze auch über Klassen realisieren. Die erben immer von der Basisklasse TObject. Details zu Klassen und OOP kannst Du in vielen Tutorials nachlesen, die meisten behandeln sicherlich auch Vererbung (und vergessen dafür häufiger mal die wichtigen Ideen der OOP).
Jedenfalls kannst Du jede Instanz einer Klasse immer wie eine TObject Instanz behandeln. Dabei siehst Du dann nur dass, was eben ein TObject anbietet (z.B. die Methode Free zum Freigeben der Instanz).
Hier kannst Du also auf ein Object of TObject oder eine TObjectList zurückgreifen. Ob eine Instanz nun vom Typ Klasse1 oder Klasse2 ist, kannst Du mittels dem Operator is (if Variable is TKlasse1 then ...) testen.

Gruß Der Unwissende
  Mit Zitat antworten Zitat