Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   record mit dynamischem objekt (https://www.delphipraxis.net/191786-record-mit-dynamischem-objekt.html)

Pixel 19. Feb 2017 10:19

Delphi-Version: 5

record mit dynamischem objekt
 
Hallo,

ich wusste nicht wie ich den Titel vergeben sollte, ist wahrscheinlich falsch, naja ich beschreibe mal mein Vorhaben.

Ich habe diese 4 records:

Delphi-Quellcode:
 
  TDot = packed record
    Coordinates : TPoint;
    Offset : Integer;
  end;

  TSlider = packed record
    Coordinates : array of TPoint;
    Offset : Integer;
    Length : Single;
    SliderType : TSliderType;
    Repetitions : Integer;
  end;

  TSpinner = packed record
    Offset : Integer;
    Length : Integer;
  end;

  THitObject = packed record
    Coordinates : array[0..0] of Integer;
    Offset : Integer;
    HitObjectType : THitObjectType;
    HitObject : Pointer;
  end;
Im Prinzip geht es um das letzte record
Delphi-Quellcode:
THitObject
. Man sieht am Ende die Deklaration
Delphi-Quellcode:
HitObject : Pointer
. Hier würde ich gerne in Abhgängikeit von
Delphi-Quellcode:
HitObjectType
(
Delphi-Quellcode:
TDot
,
Delphi-Quellcode:
TSlider
oder
Delphi-Quellcode:
TSpinner
), was während der Laufzeit bekannt wird, das zugehörige Objekt in
Delphi-Quellcode:
HitObject
stehen haben.

Also angenommen
Delphi-Quellcode:
HitObjectType
wäre
Delphi-Quellcode:
TSpinner
, dann sollte
Delphi-Quellcode:
HitObject
ein
Delphi-Quellcode:
TSpinner
sein.

Mein Ansatz:

Ich glaube man müsste die Objekte global deklarieren, also z.B. in private, weil sie sonst nicht mehr gültig sein würden, bei Beendigung der Prozdeur wo das alles ermittelt wird oder?

Also:
Delphi-Quellcode:
private
  var Sliders : array of TSlider;
Und dann in zur Laufzeit mit
Delphi-Quellcode:
SetLength(Sliders, X)
und
Delphi-Quellcode:
HitObject := @Sliders[X]
.

Mir kommt das unsauber vor.


Wie würdet ihr sowas machen?

DeddyH 19. Feb 2017 10:34

AW: record mit dynamischem objekt
 
Ich habe zwar den Zusammenhang überhaupt nicht verstanden, aber wenn es darum geht, zu ermitteln, was konkret in Deinem HitObject-Feld steht, könntest Du doch statt der Records gleich Klassen verwenden. Zur Laufzeit ermittelst Du dann mit is, welche konkrete Klasse das ist.
Delphi-Quellcode:
type
  TMyObject = class
  private
    FOffset: integer;
  public
    property Offset: integer read FOffset write FOffset;
  end;
 
  TSpinner = class(TMyObject)
  private  
    FLength : Integer;
  public
    property Length: integer read FLength write FLength;
  end;
Das Feld in THitobject ist dann vom Typ TMyObject statt Pointer.
Delphi-Quellcode:
if HitObject.HitObject is TSpinner then
  TSpinner(HitObject.HitObject).Length := 42;
Noch eleganter wären zwar Interfaces, ich weiß aber nicht, ob Du damit klarkommst.

Fritzew 19. Feb 2017 10:37

AW: record mit dynamischem objekt
 
In etwa so:
Als Variante records
Delphi-Quellcode:
THitObject = record
    Coordinates: array [0 .. 0] of Integer;
    Offset: Integer;
    case HitObjectType: THitObjectType of
      hDot: (Dot: TDot);
      hSlider: (Slider: TSlider);
      hSpinner: (Spinner: TSpinner);
  end;
Warum verwendest Du packed records? Die sind im Zugriff eher langsamer;

jfheins 19. Feb 2017 10:39

AW: record mit dynamischem objekt
 
Zitat:

Zitat von Pixel (Beitrag 1362054)
Wie würdet ihr sowas machen?

Ich würde den Kram als Klassen deklarieren (TDot, TSlider und TSpinner haben eine gemeinsame Basisklasse) und dann abfragen:
Delphi-Quellcode:
if myObj.HitObject is TSpinner then ...
Oder gleich den Codeschnipsel in die Klassen verlagern und sort aufrufen.


Falls es unbedingt records sein müssen: Du kannst als erstes Feld ein "Typfeld" implementieren und dort immer den richtigen Typ reinschreiben. Beim auslesen kannst du dann den pointer weitersetzrn, das Feld auslesen und entsprechend reagieren.

Pixel 19. Feb 2017 10:53

AW: record mit dynamischem objekt
 
Zitat:

Zitat von Fritzew (Beitrag 1362057)
In etwa so:
Als Variante records
Delphi-Quellcode:
THitObject = record
    Coordinates: array [0 .. 0] of Integer;
    Offset: Integer;
    case HitObjectType: THitObjectType of
      hDot: (Dot: TDot);
      hSlider: (Slider: TSlider);
      hSpinner: (Spinner: TSpinner);
  end;
Warum verwendest Du packed records? Die sind im Zugriff eher langsamer;

Das war genau das was ich gesucht hatte! Vielen Dank! Ich hatte sogar irgendetwas mit case im Kopf, aber dachte dann dass ich das nur aus c++ gekannt habe oder so. Naja.

Und warum packed records? Naja ich hatte anfangs auf den Speicher direkt zugegriffen und wollte dann kein alignment haben, habs aber wieder zu record geändert jetzt!


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