AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Sonstige Fragen zu Delphi Delphi Wie eigenen Record definieren und verwenden?
Thema durchsuchen
Ansicht
Themen-Optionen

Wie eigenen Record definieren und verwenden?

Ein Thema von TonyMontana · begonnen am 15. Jan 2008 · letzter Beitrag vom 16. Jan 2008
Antwort Antwort
Seite 1 von 2  1 2      
TonyMontana
(Gast)

n/a Beiträge
 
#1

Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 17:52
Also, ich habe eine Frage zu folgender Definition meines Records:

Delphi-Quellcode:
type
  TMyRec = record
  Value : Integer;
  Text : String;
  StringList : TStringList;
end;
So habe ich den erstmal definiert. Ich dachte jetzt, ich kann einfach eine Variable folgendermaßen deklarieren und dann benutzen:

Delphi-Quellcode:
var
 MyRec: TMyRec;
Dann habe ich einfach mal den Feldern Werte zugewiesen, so:

Delphi-Quellcode:
begin
 With MyRec do begin
  Value := 0;
  Text := 'bla';
  StringList.Text := ListBox.Items.Text //<-- Fehler
 end;
end;
An markierter Stelle erhalte ich dann eine Zugriffsverletzung...
Wer kann mir erklären, wie ich den Record profi-mäßig benutze
Ich vermute mal, ich muss wohl noch Speicher reservieren?!
Dabei sah das in der Delphi-Hilfe so aus, als ob man einfach nur die Variable deklarieren muss und Delphi den rest erledigt ...
Ich bekomme ja auch erst die Zugriffsverletzung bei der StringList, ist das ein unzulässiges Feld???
Oder muss ich irgendwie sowas verwenden?:

Delphi-Quellcode:
 
 MyRec.StringList := TStringList.Create;
 ...
 MyRec.StringList.Free;
Ist halt ne eigene Klasse, das TStringList... Aber ich glaube, mit Constructor und Destructor ging es auch nicht ohne schwere Fehler.

Ich bin aber auch ein Anfänger
  Mit Zitat antworten Zitat
dominikkv

Registriert seit: 30. Sep 2006
Ort: Gundelfingen
1.109 Beiträge
 
Delphi 2007 Professional
 
#2

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 17:59
Zitat von TonyMontana:
Ich vermute mal, ich muss wohl noch Speicher reservieren?!
jup
Zitat von TonyMontana:
Dabei sah das in der Delphi-Hilfe so aus, als ob man einfach nur die Variable deklarieren muss und Delphi den rest erledigt ...
nope
Zitat von TonyMontana:
Ich bekomme ja auch erst die Zugriffsverletzung bei der StringList, ist das ein unzulässiges Feld???
Zitat von TonyMontana:
Oder muss ich irgendwie sowas verwenden?:
Delphi-Quellcode:
 
 MyRec.StringList := TStringList.Create;
 ...
 MyRec.StringList.Free;
jo
Dominik
Wer anderen eine Grube gräbt, hat ein Gruben-Grab-Gerät!
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.755 Beiträge
 
Delphi 10.4 Sydney
 
#3

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 18:00
Guten Abend,

wenn Du die StringList im Record benutzen willst,
solltest Du sie auch vorher erstellen.

MyRec.StringList := TStringList.create; Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 18:07
Und du musst sie auch selber wieder löschen.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
TonyMontana
(Gast)

n/a Beiträge
 
#5

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 18:16
Ok funktioniert jetzt ohne Fehler

Hatte ich wohl überlesen in der Delphi Hilfe, dass man für Felder, die Instanzen von Klassen sind Speicher reservieren muss...

Aber dann ist doch das Feld an sich nicht _unzulässig_, sondern erfordert nur eine Speicherreservierung, die man selbst vornehmen muss, oder? Immerhin wird es ja kompiliert.

Ist noch alles etwas undurchsichtig für mich, wann ich Speicher reservieren muss und wann das Delphi selbst erledigt, gerade auch bei Strings und so...

Kann mir jemand verraten, wo man das -verständlich- nachlesen kann? Ich finde die Delphi Hilfe nicht immer optimal muss ich sagen...

Ach ja, falls ich die StringList öfter mal benutzen möchte, wäre es ja blödsinn, für diese ständig Speicher zu reservieren und freizugeben. Wo packe ich dann am besten das MyRec.StringList := TStringList.Create; und MyRec.StringList.Free; hin? Das Erste am besten im OnCreate Ereignis des Formulars und das Zweite wohl am besten im OnDestroy Ereignis des Formulars, oder?

Danke schonmal für die schnellen Antworten.
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.542 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 18:18
Wenn Du mit Instanzen von Klassen arbeiten willst, solltest Du statt eines Records eine eigene Klasse definieren, die sich um die einzelnen Instanzen kümmert.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
TonyMontana
(Gast)

n/a Beiträge
 
#7

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 18:34
Ok, würde ich gerne. Leider bin ich noch nicht so fit in diesen Sachen. Wie sähe das dann ungefähr aus?
  Mit Zitat antworten Zitat
Christian Seehase
(Co-Admin)

Registriert seit: 29. Mai 2002
Ort: Hamburg
11.105 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 18:57
Moin Tony,

Zitat von TonyMontana:
Hatte ich wohl überlesen in der Delphi Hilfe, dass man für Felder, die Instanzen von Klassen sind Speicher reservieren muss...
Ich fürchte, ich muss Deine Verwirrung erst noch einmal etwas steigern.

Die Felder sind keine Instanzen von Klassen, sondern können Zeiger auf Instanzen von Klassen enthalten.
Das mit dem Zeiger ist jetzt nicht der Knackpunkt, da dies eh der normale Weg ist auf Instanzen zuzugreifen.
Wichtiger ist, dass man nicht den Speicher für die Felder, sondern für die Instanzen der Klassen reservieren muss.
Man kann diesen Feldern ja schliesslich auch die Adressen von Instanzen zuweisen, die man auch noch ganz woanders erzeugt, und gespeichert hat.

Ein Beispiel:
Ich habe eine TObjectList, in der ich eine Reihe von Objekten gespeichert habe.
Nun möchte ich diese gerne in einer Liste ausgeben.
Um den Zugriff zu erleichtern übergebe ich nun jedes Objekt, der Reihe nach, an eine Variable des gespeicherten Typs, und kann dann mit dieser arbeiten, ohne, dass ich hierfür noch einmal extra Speicher reservieren muss:

Delphi-Quellcode:
TMyEntry = class(TObject)
private
  FsTitel : string
  FsInhalt : string;
public
  property Titel : string read FsTitel write FsTitel;
  property Name : string read FsName write FsName;
end;

TMyList = class(TObjecList)
end;

// Fml soll hier ein Feld vom Typ TMyList sein
// lv soll hier ein TListView sein

var
  me : TMyEntry;
  i : integer;
  li : TListItem;

begin
  for i := 0 to ml.Count-1 do begin
    li := lv.Items.Add;
    // Es wird kein Speicher reserviert, da dies schon früher passiert ist
    // und die Adresse ist in der Objektliste gespeichert
    me := ml[i] as TMyEntry;
    li.Caption := me.Titel;
    li.SubItems.Add(me.Name);
  end;
end;
Zitat von TonyMontana:
Aber dann ist doch das Feld an sich nicht _unzulässig_, sondern erfordert nur eine Speicherreservierung, die man selbst vornehmen muss, oder? Immerhin wird es ja kompiliert.
Das Feld selber ist ja auch völlig OK, nur enthält es nichts sinnvolles, aber das interessiert den Compiler nicht

Zitat von TonyMontana:
Ist noch alles etwas undurchsichtig für mich, wann ich Speicher reservieren muss und wann das Delphi selbst erledigt, gerade auch bei Strings und so...
Ganz genau genommen, reservierst Du auch bei Strings den Speicher selber, nur fällt das nicht so auf, wie bei Objekten.
Wenn Du, z.B., aus einem TFileStream lesen willst, so kannst Du hierfür einen String nehmen:

Delphi-Quellcode:
var
  fs : TFileStream;
  sBuf : string;

begin
  fs := TFileStream.Create('Pfad zur Datei',fmOpenRead);
  try
    // Und hier knallt es, weil eben kein Speicher für den String reserviert wurde.
    fs.Read(sBuf[1],fs.Size);
    // was man so lösen kann:
    SetLength(sBuf,fs.Size);
    fs.Read(sBuf[1],fs.Size);
  finally
    fs.Free;
  end;
end;
Grundsätzlich kannst Du sagen:
Wenn Du mit einem Zeiger arbeiten willst, muss der vorher etwas sinnvolles enthalten.
Objekte sind, auch wenn die Compilermagic das verschleiert, nichts weiter als Zeiger.

(Es gibt Ausnahmen, da es Funktionen gibt, die die Speicherreservierung selbständig machen, aber das ist dann bei denen auch meist dokumentiert, da man, i.d.R., den Speicher dann trotzdem selber freigeben muss.)

Zitat von TonyMontana:
Kann mir jemand verraten, wo man das -verständlich- nachlesen kann? Ich finde die Delphi Hilfe nicht immer optimal muss ich sagen...
Ich hoffe es ist verständlicher geworden, wenn nicht, frag' einfach noch mal nach.

Zitat von TonyMontana:
Das Erste am besten im OnCreate Ereignis des Formulars und das Zweite wohl am besten im OnDestroy Ereignis des Formulars, oder?
Das wäre eine gute Position.
Für die Stelle an der man ein Objekt instanziert, bzw. wieder freigibt, gibt es allerdings kein Patentrezept.
Grundsätzlich sollte man es so spät wie möglich erzeugen, und so früh wie möglich wieder freigeben.
(das gilt für alle Resourcen, z.b. auch Handles)
Tschüss Chris
Die drei Feinde des Programmierers: Sonne, Frischluft und dieses unerträgliche Gebrüll der Vögel.
Der Klügere gibt solange nach bis er der Dumme ist
  Mit Zitat antworten Zitat
TonyMontana
(Gast)

n/a Beiträge
 
#9

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 20:48
Zitat von DeddyH:
Wenn Du mit Instanzen von Klassen arbeiten willst, solltest Du statt eines Records eine eigene Klasse definieren, die sich um die einzelnen Instanzen kümmert.
Was meinst du damit, dass sich die Klasse um die einzelnen Instanzen kümmert? Bedeutet das, dass die Klasse dann automatisch Speicher reserviert und freigibt oder muss ich dann in dieser neuen Klasse TMyRec, abgeleitet von TObject, dann noch den Constructor und Destructor überschreiben?

Bisher sah das ganze ja so aus:
Delphi-Quellcode:
type
  TMyRec = record
  Value : Integer;
  Text : String;
  StringList : TStringList;
end;
Wie sähe dann eine Klasse aus, die oben stehende Felder bereitstellt?

Das ist warscheinlich kompletter unsinn:
Delphi-Quellcode:
type
  TMyRec = class(TObject)
private
  mrValue: Integer;
  mrText: String;
  mrStringList: TStringList;
public
  property Value: Integer read mrValue write mrValue;
  property Text: string read mrText write mrText;
  constructor Create;
  destructor Destroy;
end;

implementation

constructor TMyRec.Create;
begin
 inherited;
 // mrStringList Speicher reservieren?
end;

destructor TMyRec.Destroy;
begin
// mrStringList Speicher freigeben
inherited;
end;
Property für mrStringList fehlt, ich habe mal angenommen man setzt sowas wie mr vor die Felder um die zugehörigkeit zu verdeutlichen, mr steht für MyRec...
Wie reserviere ich den Speicher jetzt im Constructor bzw. gebe ihn im Destructor wieder frei?

Oder ist das nicht möglich oder empfehlenswert?

Ich bin ratlos.

Edit: Das mit der Compilermagic habe ich irgednwie nicht verstanden, was ist das? Also im Prinzip meinst du damit, dass ich nicht merke, dass ich mit Zeigern arbeite, oder?
Ist dann also jedes Feld eines Objekts ein Zeiger? Warum muss ich dann für den String und den Integer keinen Speicher reservieren?
Ich meine, beim Integer kann ich mir denken, dass automatisch speicher reserviert werden kann, ein integer hat ja eine feste größe aber die Strings können doch soweit ich weiß fast beliebig groß sein.
  Mit Zitat antworten Zitat
Progman

Registriert seit: 31. Aug 2007
Ort: 99974 MHL
695 Beiträge
 
Delphi 10.1 Berlin Starter
 
#10

Re: Wie eigenen Record definieren und verwenden?

  Alt 15. Jan 2008, 22:04
Delphi-Quellcode:
constructor TMyRec.Create;
begin
inherited;
 mrStringList:=TStringList.Create;
end;

destructor TMyRec.Destroy;
begin
 mrStringList.Free;
inherited;
end;
So einfach
Karl-Heinz
Populanten von Domizilen mit fragiler, transparenter Aussenstruktur sollten sich von der Translation von gegen Deformierung resistenter Materie distanzieren!
(Wer im Glashaus sitzt sollte nicht mit Steinen werfen)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:21 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