Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   records oder klassen? (https://www.delphipraxis.net/189248-records-oder-klassen.html)

JayZ 21. Mai 2016 17:46

records oder klassen?
 
hey ich habe einge frage und zwra wann sollte man klassen brauchen und wann sollte man records verwenden? kann ich in recrods auch objekte absperichern und falls ja wie mache ich das mit dem konstruktor den ndas geht ja bei einem recrod gar nicht? danke schon mal!:stupid:

jaenicke 21. Mai 2016 17:53

AW: records oder klassen?
 
Das wäre einfacher, wenn du einen konkreten Anwendungsfall nennen würdest.

Allgemein würde ich in den meisten Fällen Klassen benutzen.
Auch zum Beispiel in Kombination mit Interfaces.

Ausnahmen sind zum Beispiel, wenn du Klassenoperatoren verwenden möchtest oder direkt mit reserviertem Speicher arbeiten möchtest, zum Beispiel zur Nutzung der Windows API.

JayZ 21. Mai 2016 19:07

AW: records oder klassen?
 
Zitat:

Zitat von jaenicke (Beitrag 1338639)
Das wäre einfacher, wenn du einen konkreten Anwendungsfall nennen würdest.

Allgemein würde ich in den meisten Fällen Klassen benutzen.
Auch zum Beispiel in Kombination mit Interfaces.

Ausnahmen sind zum Beispiel, wenn du Klassenoperatoren verwenden möchtest oder direkt mit reserviertem Speicher arbeiten möchtest, zum Beispiel zur Nutzung der Windows API.

also ich weiss nicht ich habe records gerade erste endtdeckt wofür wäre es zum beispielk dnn gut? ich kann ja dort auch funktionen erstellen also wofrür ein objekt erstellen wenn ich recrods benutzen kann? was ist denn klassenoperationen?

mkinzler 21. Mai 2016 19:21

AW: records oder klassen?
 
Beispiel Komplexe Zahl:


Ohne Class Operator:

Delphi-Quellcode:
TComplex = Record
  r: Double;
  i:Double;
End;

function ComplexAdd ( a, b: TComplex); TComplex;

...

c := ComplexAdd(a, b);
Mit

Delphi-Quellcode:
TComplex = Record
  r: Double;
  i:Double;
  Class Operator Add( a, b: TComplex); TComplex;
End;

...

c := a + b;

recall 23. Mai 2016 07:30

AW: records oder klassen?
 
"Historisch" gesehen waren records einmal Klassen, die nur Eigenschaften hatten (keine Methoden etc.). Allerdings sind diese beiden Datentypen immer mehr zusammengrückt, weswegen die Abgrenzung inzwischen etwas schwerer zu verstehen ist. Manchmal wird (auch eher historisch bedingt) das eine oder andere von APIs vorgegeben. Ich denke nicht, dass da man eine allgemeine Regel formulieren sollte, wann man was benutzt. "Falsch" ist keines von beiden.

Hier etwas zu Records:
https://www.delphi-treff.de/object-p...datentypen/#m9

Und hier was zu Klassen:
https://www.delphi-treff.de/object-p...n-und-objekte/

Klassenfunktionen sind übrigens Funktionen, die aufgerufen werden können, ohne dass ein Objekt einer Klasse erzeugt werden muss. Damit kann man natürlich innerhalb so einer Klassenfunktion nicht auf Variablen der Klasse zugreifen, weil ja kein Speicher reserviert wurde (d.h. kein Objekt erstellt).

jaenicke 23. Mai 2016 07:58

AW: records oder klassen?
 
Der Hauptunterschied bleibt aber:
Bei Klassen arbeitet man mit Pointern, bei Records muss man diese explizit benutzen und den Speicher auch ggf. Selbst reservieren und freigeben.

bra 23. Mai 2016 10:24

AW: records oder klassen?
 
Zitat:

Zitat von jaenicke (Beitrag 1338677)
Der Hauptunterschied bleibt aber:
Bei Klassen arbeitet man mit Pointern, bei Records muss man diese explizit benutzen und den Speicher auch ggf. Selbst reservieren und freigeben.

Irgendwie klingt der Satz für mich falsch.

Records: müssen nicht erzeugt und freigegeben werden
Klassen: müssen erzeugt und wieder freigegeben werden (Create...Free)

p80286 23. Mai 2016 10:25

AW: records oder klassen?
 
Zitat:

Zitat von jaenicke (Beitrag 1338677)
Der Hauptunterschied bleibt aber:
Bei Klassen arbeitet man mit Pointern, bei Records muss man diese explizit benutzen und den Speicher auch ggf. Selbst reservieren und freigeben.

Hast Du Dich da ein wenig verformmuliert?
Gerade bei der Nutzung von Klassen kann man das Pointer-Gewusel gut umgehen. Intern sieht das ein wenig anders aus. Und der/die nackte Record hat erst einmal nichts mit Pointern zu tun.
Daß Pointer und Records ein leistungsfähiges Gespann sind, würde ich nie in Abrede stellen.

Gruß
K-H

Edith:
Zitat:

Zitat von bra (Beitrag 1338690)
Records: müssen nicht erzeugt und freigegeben werden
Klassen: müssen erzeugt und wieder freigegeben werden (Create...Free)

Jain, wenn records in einem (statischen)Array genutzt werden ist das richtig. Hast Du z.B. eine einfach verkettete Liste, dann in den allermeisten Fällen nicht.

Christian Seehase 23. Mai 2016 10:49

AW: records oder klassen?
 
Moin recall,

Zitat:

Zitat von recall (Beitrag 1338675)
"Historisch" gesehen waren records einmal Klassen, die nur Eigenschaften hatten (keine Methoden etc.).

das dürfte wohl darauf ankommen, wie weit Du in der Historie zurückgehst.
Ursprünglich dienten Records dazu Daten strukturiert speichern und laden zu können. :wink:
(da waren Klassen bestenfalls in der Idee vorhanden)

Grundsätzlich wäre das dann wohl auch ein Anwendungszweck, bei dem man um Records kaum herumkommt.
(auch wenn bei der heutigen Verbreitung von (lokalen) Datenbanken und xml der Bedarf nicht mehr so hoch sein dürfte).

Wann auch immer Pointer ins Spiel kommen, man um zugeordnete Funktionen/Prozeduren nicht herumkommt oder diese
Datenstrukturen anderweitig zugeordnet werden müssen (z.B. als Object eines Eintrags einer StringListe, würde ich
wohl meist auf eine Klasse zurückgreifen.
Als Rückgabewert einer Funktion kann es mit einer Klasse schwierig werden, hier wäre dann wohl ein Record sinnvoller.
In diesem Falle könnte man dann, ersatzweise, aich einen const Parameter mit einer Klasse übergeben.

Rollo62 23. Mai 2016 11:48

AW: records oder klassen?
 
http://delphi.about.com/od/windowssh...developers.htm

Rollo

p80286 23. Mai 2016 12:22

AW: records oder klassen?
 
Und was hat der Unterschied zwischen Stack und Heap jetzt mit Records und Klassen zu tun?
(naja einen Berührungspunkt wird man bestimmt finden)

Gruß
K-H

bra 23. Mai 2016 13:10

AW: records oder klassen?
 
Zitat:

Zitat von p80286 (Beitrag 1338714)
Und was hat der Unterschied zwischen Stack und Heap jetzt mit Records und Klassen zu tun?

Records werden auf dem Stack erstellt, Klassen auf dem Heap. Daher auch der Unterschied mit Erstellen/Freigeben.

Sir Rufo 23. Mai 2016 13:30

AW: records oder klassen?
 
Zitat:

Zitat von bra (Beitrag 1338721)
Zitat:

Zitat von p80286 (Beitrag 1338714)
Und was hat der Unterschied zwischen Stack und Heap jetzt mit Records und Klassen zu tun?

Records werden auf dem Stack erstellt, Klassen auf dem Heap. Daher auch der Unterschied mit Erstellen/Freigeben.

Ist es nicht eher genau anders herum?

Ein Record ist ein Bei Google suchenValue Type und eine Klasse ist ein Bei Google suchenReference Type. Aufgrund dessen erfolgt die Ablage auf dem Stack bzw. Heap.

bra 23. Mai 2016 13:40

AW: records oder klassen?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1338722)
Ein Record ist ein Bei Google suchenValue Type und eine Klasse ist ein Bei Google suchenReference Type. Aufgrund dessen erfolgt die Ablage auf dem Stack bzw. Heap.

http://docwiki.embarcadero.com/RADSt....28advanced.29

Records are value types, so they are copied on assignment, passed by value, and allocated on the stack unless they are declared globally or explicitly allocated using the New and Dispose function. Classes are reference types, so they are not copied on assignment, they are passed by reference, and they are allocated on the heap.

Records are constructed automatically, using a default no-argument constructor, but classes must be explicitly constructed. Because records have a default no-argument constructor, any user-defined record constructor must have one or more parameters.

p80286 23. Mai 2016 16:48

AW: records oder klassen?
 
wenn ich so etwas habe:

Delphi-Quellcode:
procedure irgendwas;
var
  myrecord : myrecordtype;
begin
...
end;
dann ist es klar, das d.. auf dem Stack landet;

Bei
Delphi-Quellcode:
procedure irgendwas;
var
  pmyrecord : ^myrecordtype;
begin
  new(pmyrecord);
...
end;
Ist es der Heap der die Daten aufnimmt.

Gruß
K-H

Rollo62 23. Mai 2016 18:00

AW: records oder klassen?
 
http://docwiki.embarcadero.com/RADSt...blaufsteuerung

http://docwiki.embarcadero.com/RADSt...r_%28Delphi%29

Zitat:

Mengen, Records und statische Arrays aus einem, zwei oder vier Byte werden als 8-Bit-, 16-Bit- und 32-Bit-Werte übergeben. Größere Mengentypen, Records und statische Arrays werden als 32-Bit-Zeiger auf den Wert übergeben. Eine Ausnahme von dieser Regel ist, dass bei den Konventionen cdecl, stdcall und safecall die Records immer direkt im Stack übergeben werden. Die Größe eines auf diese Weise übergebenen Records wird immer bis zur nächsten Double-Word-Grenze erweitert.
Und ich gehe davon aus das lokale Records eben im immer Stack erzeugt werden (müsste man mal Testen wenn man viel Zeit übrig hat).
Deshalb wäre das nur für kleine Größen sinnvoll um einen Stacküberlauf zu vermeiden.

Stacküberlauf: Stammt das icht aus DOS-Zeiten, sowas habe ich schon eeewig nicht mehr gehabt (Klopf auf Holz).

Aber Segmentgrenzen-Fehler 16MB habe ich schon mehrfach gehabt, auf iOS ...
Es könnte ja sein das diese alten, vergessenen Probleme auf den mobilen Plattformen ein zweites Zombie-Dasein führen.

Rollo

freimatz 26. Mai 2016 14:30

AW: records oder klassen?
 
Ergänzung:
Klassen können abgeleitet werden.
Klassen können Interfaces implementieren

Mavarik 27. Mai 2016 02:28

AW: records oder klassen?
 
Zitat:

Zitat von p80286 (Beitrag 1338753)
Bei
Delphi-Quellcode:
procedure irgendwas;
var
  pmyrecord : ^myrecordtype;
begin
  new(pmyrecord);
...
end;
Ist es der Heap der die Daten aufnimmt.

Nööö bzw. das sind den hier die Daten?

"Die Daten" ist hier ein Pointer...

und genau das hat jaenicke hiermit gemeint...

Zitat:

Zitat von jaenicke (Beitrag 1338677)
Der Hauptunterschied bleibt aber:
Bei Klassen arbeitet man mit Pointern, bei Records muss man diese explizit benutzen und den Speicher auch ggf. Selbst reservieren und freigeben.

Natürlich nicht der "eine" Record, der mit einer Variablen definiert ist...

"Früher" wurden halt Records genutzt um Daten zu Speichern... Also war der Record EIN Datensatz. Da man nur 64KB Datensegment hatte, konnte man nicht beliebig viele Daten in einen Array of Record halten, sondern musste den Speicher vom HEAP anfordern. (New/Getmen)

Daher der Hinweis auf: Selber reservieren und freigeben...

Eine Klasse ist eigentlich "fast" nix anderes nur das man hier direkt den Pointer auf den Speicher hat... (Und noch ein bisschen mehr)

Also ob ich

Delphi-Quellcode:
type
  TMyDaten = Record
               Bla : Integer;
               Foo : boolean;
             end;
var
  PMyDaten = ^MyDaten;
begin
  New(PMyDaten);
  try
    PMyDaten^.Bla := 42;
  finally
    Dispose(PMyDaten);
  end;
end;
oder

Delphi-Quellcode:
type
  TMyDaten = Class
    public
      Bla : Integer;
      Foo : boolean;
  end;

Var
  MyDaten : TMyDaten;
begin
  MyDaten := TMyDaten.Create;
  try
    MyDaten.Bla := 42;
  finally
    MyDaten.Free;
  end;
end;
Ist "fast" gleich...

Mavarik

JayZ 9. Jun 2016 07:46

AW: records oder klassen?
 
ich verstehe is immer noch nicht :(
wenn ich classen benutze ist ja klar das ich die erstellen (create) und löschen (free) muss wie sieht die speicherveerwaltung denn bei records aus? muss ich das auch freigen?

DrTight 9. Jun 2016 08:23

AW: records oder klassen?
 
Was aber auch geht ist

Code:
type
  TMyDaten = Record
    Bla : Integer;
    Foo : boolean;
  end;
var
  LMyDaten :TMyDaten;
begin
  LMyDaten = Default(TMyDaten); // Record wird Initialisiert (alle Felder auf 0)
  LMyDaten.Bla := 42;
end;
Bla = 42 und Foo wäre False
Der Record wird wie eine lokale Variable behandelt (inclusive Speicher reservieren in Recordgröße und ohne Initialisierung) die auf den Stack abgelegt wird.

Records sind nix anderes als strukturierte Variablen.
Das gute an Records ist, das man sich nicht um das Freigeben des Speichers kümmern muss (Es sei denn man verwendet New())
Auch das kopieren von Records geht einfach durch Zuweisung (Achtung: Bei Pointer ,Klassen, variablen Arrays und Methodenreferenzfeldern wird nur die Adresse kopiert nicht der Inhalt)
Sie eignen sich gut als Übergabe und Resultparameter für Functionen und Proceduren.

Bambini 9. Jun 2016 08:24

AW: records oder klassen?
 
Zitat:

Zitat von JayZ (Beitrag 1339802)
ich verstehe is immer noch nicht :(
wenn ich classen benutze ist ja klar das ich die erstellen (create) und löschen (free) muss wie sieht die speicherveerwaltung denn bei records aus? muss ich das auch freigen?

Ja, wenn man diese mit New() erzeugt.

Blup 9. Jun 2016 08:28

AW: records oder klassen?
 
Das hängt davon ab, wie du Records benutzt.
Allgemein kann man sagen:

Wird ein Record als Zeiger deklariert:
- mit New() erstellen und dem Zeiger zuweisen
- mit Dispose() freigegeben (Zeiger ist danach ungültig)
Delphi-Quellcode:
type
  PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID: Integer;
    Name: string;
  end;

var
  P: PMyRecord;
begin
  New(P);
  try
    TuWasMit(P);
  finally
    Dispose(P);
  end;
end;
Wird ein Record direkt als Variable deklariert, kümmert sich der Compiler:
- um die Bereitstellung des Speichers beim Eintritt in den Gültigkeitsbereich
- um die Freigabe des Speichers beim Verlassen des Gültigkeitsbereichs
Delphi-Quellcode:
type
  PMyRecord = ^TMyRecord;
  TMyRecord = record
    ID: Integer;
    Name: string;
  end;

var
  R: TMyRecord;
begin
  TuWasMit(^R);
end;

bra 9. Jun 2016 08:50

AW: records oder klassen?
 
Zitat:

Zitat von JayZ (Beitrag 1339802)
ich verstehe is immer noch nicht :(
wenn ich classen benutze ist ja klar das ich die erstellen (create) und löschen (free) muss wie sieht die speicherveerwaltung denn bei records aus? muss ich das auch freigen?

Nein, eben nicht. Das macht es einfacher, weil man Records z.B. als Parameter oder Rückgabewert von Funktionen verwenden kann, ohne sich Gedanken machen zu müssen, wo man die wieder freigeben muss. Allerdings wird der Speicherverbrauch bei exzessiven Gebrauch dann höher sein, weil bei jedem Parameter der übergeben wird, eine Kopie des Records erstellt wird.

Blup 9. Jun 2016 11:46

AW: records oder klassen?
 
Ob bei der Parameterübergabe eine Kopie oder nur eine Referenz (praktisch ein Zeiger auf den übergebenen Record, aber vor dem Entwickler verborgen) übergeben wird, kann man aber mit den Schlüsselworten const, var oder out steuern.
Delphi-Quellcode:
procedure TuWasMitPointer(P: PMyRecord);
begin
  P^.ID  := 1;
  P^.Name := 'Test';
end;

procedure TuWasMitReferenz(var R: TMyRecord);
begin
  R.ID  := 1;
  R.Name := 'Test';
end;

procedure TuWasMitReferenz(out R: TMyRecord);
begin
  R.ID := 1;
  R.Name := 'Test';
end;
Die Prozeduren erzeugen genau den selben Code. Der Compiler führt beim Compilieren aber unterschiedliche Prüfungen aus und kann den Entwickler so bei falscher Benutzung warnen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:33 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