![]() |
Datenkopie vom einen Record in ein anderes
Hallo zusammen,
ich hätte da mal eine Frage zum Kopieren von Daten zwischen zwei Records.
Delphi-Quellcode:
aber was ist wenn ich
type
tMyRecord1 : packed record datum : tdatetime; wert : integer; feld : string[255]; end; var record1 : tMyrecord1; record2 : tMyrecord1; // So funktioniert es immer record1.datum:=record2.datum; record1.wert:=record2.wert; record1.feld:=record2.feld; //so geht es auch move(record2,record1,sizeof(tMyrecord));
Delphi-Quellcode:
oder
type
tMyRecord1 : packed record datum : tdatetime; wert : integer; feld : AnsiString; end;
Delphi-Quellcode:
verwende?
type
tMyRecord1 : packed record datum : tdatetime; wert : integer; feld : String; end; dann sollte doch mit einem
Delphi-Quellcode:
nur die Stringadresse kopiert werden und Änderungen in
move(record2,record1,sizeof(tMyrecord));
Delphi-Quellcode:
hätten gleichzeitig Änderungen in
record2.feld
Delphi-Quellcode:
zur Folge?
record1.feld
Oder liege ich da falsch? Gruß K-H |
AW: Datenkopie vom einen Record in ein anderes
Ich verstehe nicht- Warum sollte man das tun? Record-Zuweisungen sind doch immer eine vollständige Kopie:
Delphi-Quellcode:
program Project16;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type TMyRecord1 = packed record datum : tdatetime; wert : integer; feld : AnsiString; end; var firstRecord, secondRecord: TMyRecord1; begin try firstRecord.datum := Now(); firstRecord.wert := 42; firstRecord.feld := 'Hallo Welt'; secondRecord := firstRecord; firstRecord.datum := 0.0; firstRecord.wert := 99; firstRecord.feld := 'Derp'; WriteLn( DateTimeToStr(secondRecord.datum) ); WriteLn(secondRecord.wert); WriteLn(secondRecord.feld); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; readln; end. |
AW: Datenkopie vom einen Record in ein anderes
Zitat:
Bei records habe ich es mir angewöhnt immer eine Assign-Procedure einzubauen. Ich scheue "move" wie der Teufel das Weihwasser.
Delphi-Quellcode:
type
TMyRecord1 = packed record datum : tdatetime; wert : integer; feld : AnsiString; Procedure assign(aSource:TMyRecord1); end; implementation Procedure assign(aSource:TMyRecord1); begin datum := aSource.adatum; wert := aSource.wert; feld := aSource.feld; end; |
AW: Datenkopie vom einen Record in ein anderes
Komischerweise passiert das bei dem Beispiel nicht ;)
|
AW: Datenkopie vom einen Record in ein anderes
Eben. Da wir hier AnsiStrings haben geht es wohl um Windows. Strings sind Copy on Write. Wenn sich ein String ändert, ändert er nur den Pointer und lässt diesen nun auf einen neuen Speicherbereich zeigen.
|
AW: Datenkopie vom einen Record in ein anderes
Zitat:
Dennoch versuche ich das Kopieren von Speicherbereichen zu vermeiden.:lol: |
AW: Datenkopie vom einen Record in ein anderes
Zitat:
Nicht daß wir uns falsch verstehen, eigentlich bevorzuge ich Pointer (da weiß man was man hat) aber wenn nur Werte vorhanden sínd/übergeben werden ist eine narrensichere allgemeingültige Verfahrennsweise ganz angenehm. Gruß K-H |
AW: Datenkopie vom einen Record in ein anderes
Ich finde, bei reinen Pointern weiß man eigentlich nicht im geringsten mehr was man hat. :-D Wenn die Motivation ist, einen Record zu kopieren reicht
Delphi-Quellcode:
Narrensicherer geht es doch nicht ;-)
meineKopie := einAndererRecord;
Auch: Ich habe in meinem Leben noch nie Move(..) benutzt- String ist doch schon ein "managed" Type: Er hat einen Referenzzähler. Allein den machst du dir mit einer reinen Byte-Kopie schon kaputt: Er ist um eins zu niedrig. |
AW: Datenkopie vom einen Record in ein anderes
NEIN!
Der Move von Records mit dynamischen Elementen ist i.d.R. falsch, da wie due geschrieben hast nur die Pointer kopiert werden. Ein
Delphi-Quellcode:
Macht intern eigentlich ein
SecondRecord := FirstRecord;
Delphi-Quellcode:
Bei einer Zuweisung eines Records auf einen anderen, will man doch den Inhalt kopieren und nicht die Referenz...
SecondRecord.Feld := FirstRecord.Feld; // Natürlich für alle Elemente
Daher ist ein Assign nicht nötig... Mavarik |
AW: Datenkopie vom einen Record in ein anderes
Um es nochmal klar zu erwähnen:
Ich rate grundsätzlich von Move und Co. ab (außer wenn es wirklich nicht anders geht, aber wenn, dann muß man ganz genau aufpassen was man da für Mist verzapft) Und für die Zuweisung zweier Records, von gleichem/kompatiblem Typ, ist das garnicht nötig, da die Zuweisung via
Delphi-Quellcode:
alles Wichtige erledigt.
:=
Vorallem bezüglich der Referenzzählung von LongStrings, dynamischen Arrays, Interfaces, Variants usw. Ein ShortString (z.B.
Delphi-Quellcode:
) ist wie ein Record, statisches Array oder einfach gesagt wie ein Integer anzusehn und bereitet die wenigsten Probleme, unter den Strings.
string[255]
Zitat:
Delphi-Quellcode:
) und alles ist im Arsch.
String
Wer unbedingt einen "Move"-Befehl verwenden will, der hat dafür New/Initialize/InitializeRecord/InitializeArray, Dispose/Finalize/FinalizeRecord/FinalizeArray und Copy/CopyArray/CopyRecord aus der System-Unit verwenden. |
AW: Datenkopie vom einen Record in ein anderes
Zitat:
Delphi-Quellcode:
mit Records nicht funktioniert
:=
und natürlich an alle anderen auch vielen Dank! Irgendwann werd' auch ich die Stringmagie verstehen, und nichts ist besser als Pointer! (wenn man weiß was man tut) Vielen Dank nochmals K-H |
AW: Datenkopie vom einen Record in ein anderes
In aktuelleren Delphis wurde die OH überarbeitet. (k.A. wann genau)
Und man kann da ganz genau nachlesen wie die Strings intern Funktionieren. (falls man das nicht persönlich in der System.pas erkunden will) |
AW: Datenkopie vom einen Record in ein anderes
Aber das habe ich doch ganz am Anfang direkt gesagt?
Niemand nimmt mich ernst. |
AW: Datenkopie vom einen Record in ein anderes
Zitat:
|
AW: Datenkopie vom einen Record in ein anderes
Zitat:
|
AW: Datenkopie vom einen Record in ein anderes
Zitat:
![]() |
AW: Datenkopie vom einen Record in ein anderes
@den schönsten aller Männer
Doch wir nehmen Dich ernst, aber laß die Finger von den Bachblüten, die bekommt unser Hund wenn wir auf Reisen gehen:drunken: Gruß K-H |
AW: Datenkopie vom einen Record in ein anderes
Zitat:
|
AW: Datenkopie vom einen Record in ein anderes
Zitat:
Wenn Du mal den Record einem anderen zuweisen musst nimmst Du den IMPLIZIET Operator und kannst alles da drin machen. Zitat:
Nur wenn Du Feldinhalte ändern willst... Sonst klingt das mehr nach dem Ruf eines Interfaces... [EDIT] |
AW: Datenkopie vom einen Record in ein anderes
Zitat:
EDIT: Anscheinend schon. Habe es allerdings noch nie wirklich gesehen. (Ich hab's übersehen) |
AW: Datenkopie vom einen Record in ein anderes
Das gibt' s IIRC seit Delphi 2006.
|
AW: Datenkopie vom einen Record in ein anderes
Zitat:
Und dann werden die Felder eines Records nur bei einem gemanagten Typen initialisiert. Und eine Objekt-Instanz ist erst mit ARC gemanaget.
Delphi-Quellcode:
TFoo = record
Instance : TObject; // ohne Zuweisung kann hier alles drin stehen! Str : string; // init mit '' Intf : IInterface; // init mit nil procedure Assign( Other : TFoo ); end; procedure TFoo.Assign( Other : Tfoo ); begin if Assigned( Instance ) then FreeAndNil( Instance ); // das knallt wie ein Zufallsgenerator! Instance := Other.Instance; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:19 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz