Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Initialisierung eines Record-Feldes (https://www.delphipraxis.net/160468-initialisierung-eines-record-feldes.html)

s.h.a.r.k 14. Mai 2011 19:32

Delphi-Version: XE

Initialisierung eines Record-Feldes
 
Hallo,

habe im Moment das Problem, dass ich ein Feld in einem Record habe, welches eigentlich initialisiert werden sollte.
Delphi-Quellcode:
TBlub = record
private
  FArray : PGenericArray; // Entweder das hier
  FBoolean : Boolean; // ... oder das hier
Hatte gerade einen constructor eingebaut, der aber nicht funktioniert hat, er wurde nicht mal angesprungen :gruebel:

Nun die Frage: wie kann ich eines der Felder denn initialisieren? Oder wird das Boolean-Feld schon automatisch initiailisiert? Habe auf die schnelle nicht gefunden.

-- EDIT: Vielleicht sollte ich noch dazu erwähnen, dass ich ein paar Operatoren überladen habe :) Ich weiß nicht, ob das hier evtl. eine Rolle spielt.

himitsu 14. Mai 2011 20:12

AW: Initialisierung eines Record-Feldes
 
Vote for Me => http://qc.embarcadero.com/wc/qcmain.aspx?d=82524

Nee, der Constructor ist leider aktuell kein "richtiger" Constructor.
Wie du bestimmt schon bemerkt hast, kann man keinen parameterlosesn Constructor erstellen ... rate mal, warum.


Antwort:
Beide Felder enthalten keine Typen mit automatischer Speicherverwaltung (wie z.B. bei String, dyn. Array oder Interface),
also werden keine deiner Felder automatisch initialisiert, sie werden auch nicht ordentlich umkopiert (z.B. bei
Delphi-Quellcode:
a := b;
) und vorallem wird nichts davon automatisch freigegeben.

Willst du eine automatische Speicherwerwaltung, wirst du mindesens einen automatischen Typen verbauen und diesen als Initialisierungsmarker mißbrauche oder gleich alle Daten z.B. in einem String, dyn. Array oder Interface ablegen.

s.h.a.r.k 14. Mai 2011 20:17

AW: Initialisierung eines Record-Feldes
 
Und Felder werden scheinbar auch nicht initialisiert :wall: Echt super das ganze...

Wenn ich aber einen String anlegen würde, dann wäre er anfangs leer?

YEAHA :mrgreen: Es geht! Danke dir, mein WE ist gerettet!!! Jetzt steht meinem Array-Record eigentlich nichts mehr im Wege. Die Tests sind auch alles okay... Geil :)

himitsu 14. Mai 2011 20:25

AW: Initialisierung eines Record-Feldes
 
Ja.

Aus diesem Grund hab ich hier mehrere Werte/Felder in soeinem automatischem Typ versteckt und die Initialisierung des Encoding wird ebenfalls über diesen automatischen Typen abgeglichen/überprüft.
http://www.delphipraxis.net/144528-s...iccharset.html

PS: Nur die String besitzen eine "ordentliche" Referenzzählung, mit automatischer Überprüfung einer Single-Instance.

Nomale dyn. Arrays verfügen nicht über sowas, was bei der Kapselung in einem Record zu problem führen kann.

Delphi-Quellcode:
var a, b: array of integer;
SetLength(a, 1);
a[0] := 1;
b := a;
b[0] := 2;
if a[0] = 1 then ShowMessage('heul');

s.h.a.r.k 14. Mai 2011 21:22

AW: Initialisierung eines Record-Feldes
 
Daher musste ich die letzten Tage meine Copy-Methode noch anpassen. Ein einfach Move() hat es in Fällen von z.B. den Strings eben nicht mehr getan.

Progman 15. Mai 2011 13:32

AW: Initialisierung eines Record-Feldes
 
wie wäre es denn mit:
Delphi-Quellcode:
TBlub = record
private
  FArray : PGenericArray; // Entweder das hier
  FBoolean : Boolean; // ... oder das hier
public
  procedure Init;
end;

procedure TBlub.Init;
begin
  //alle Defaultwerte setzen
end;

var Blub: TBlub;

//an passender Stelle einfach
Blub.Init;
Bei D2007 geht das so.

rollstuhlfahrer 15. Mai 2011 15:32

AW: Initialisierung eines Record-Feldes
 
oder gar eine Klassen-Funktion, die das initialisierte Record als Ergebnis zurückgibt.

Bernhard

s.h.a.r.k 15. Mai 2011 16:18

AW: Initialisierung eines Record-Feldes
 
Genau das will ich vermeiden, da der User dann sehr sehr oft diese Init Methode aufrufen musst. Ich brauche definitiv eine Methode die selbst ausgeführt wird oder eben eine Variable die initialisiert wird.

himitsu 15. Mai 2011 16:37

AW: Initialisierung eines Record-Feldes
 
Wie gesagt, es gib leider keine automatische Initialisierung, aber man kann sich sowas basteln.

Alle Felder auf Property umleiten und mit einer Prüfmethode versehen, ebenso alle Methoden.

Delphi-Quellcode:
type
  TMyRecord = record
  pivate
    FInitCheck: array of Byte;
    FInt: Integer;
    FBool: Boolean;
    ...
    procedure InitCheck;
  public
    property Int: Integer read GetInt write SetInt;
    property FBool: Boolean read GetBool write SetBool;
    procedure Machwas;
  end;

procedure TMyRecord.InitCheck;
begin
  if FInitCheck = nil then
  begin
    // Felder initialisieren
    ...
    SetLength(FInitCheck, 1);
  end;
end;
Und dann jeweils am Anfang aller Methoden InitCheck aufrufen.
FInitCheck wird von Windows immer als NIL initialisiert und wenn es mal kein NIL ist, dann wurde InitCheck aufgerufen.

Das umkopieren und freigeben des Records kann man so aber nicht mitbekommen.
Dafür könnte zumindestens das Freigeben, man über ein Interface bewerkstelligen, welches man statt dem Array nimmt und welchem die freizugebenden Daten (schon beim Erstellnen und bei allen wichtigen Änderungen) bekanntgemacht wurden, da das Interface keinen Zugriff auf den Record hat.
Oder man macht eben gleich alle Daten in das Interface rein und baut in den Record nurn noch Weiterleitungen ein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:14 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz