Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Prozedur-Parameter mit variantem Typ? (https://www.delphipraxis.net/22602-prozedur-parameter-mit-variantem-typ.html)

dizzy 20. Mai 2004 00:05

Re: Prozedur-Parameter mit variantem Typ?
 
Zitat:

Zitat von Tryer
Das Du nich alles auf Variants umstellen willst kann ich verstehen, der Aufwand wäre dann wirklich enorm. Komfort vs. Performance, da gibts halt wenig Kompromisse ;)

Ja leider... Ich versuch da grad nen vertretbaren Mittelweg zu finden :)

Zitat:

Zitat von Tryer
Mal nen Schnellschuss zu den Variablen:
Double, TComplex und TQuat sollten sich doch auf das folgende TNumber casten lassen (was dann bei jeder Zuweisung nötig wäre)
Delphi-Quellcode:
type
  TNumber = array [0..0] of Double;
 
  TDummy = class
  protected
    procedure SetVariable(VarName: string; const Value: TNumber);
    function GetVariable(VarName: string): TNumber;
  public
    NumberFormat: TNumberFormat;
    property Variable[VarName: string]: TNumber read GetVariable write SetVariable;
  end;
Ohne gemeinsame Basisklasse für die Variablen sehe ich keine andere Chance um sie unter einen Hut zu bekommen.

MfG,
Tryer

Das sieht an sich schon mal ganz nett aus; zumal ich dieses Konstrukt bei den properties noch nie gesehen hab! Das geht? Oder ist das Pseudocode?
Dann müsste ich zwar trotzdem an meinen Typen TComplex und TQuat drehen (die sind z.Zt. nen record und kein array), aber das könnte gehen, so denn der Cast klappt! Einziger kleiner Nachteil: Das Berechnen des Baumes mit reellen Zahlen dürfte langsamer werden. Hab dann ja keinen nativen Datentyp mehr, sondern "nur" Zeiger drauf, oder guck ich komisch? ;)
Aber das ließe sich evtl. verschmerzen. Im Moment ist der Parser bei double-Typen ca. 0,6 Mal so schnell wie eine hardgecodete Berechnung. Das ist gut genug, um davon ein klein wenig abzugeben :) (Wenn ich das jetzt total missverstanden hab, dann schrei ganz laut - ich geh' dann in die Ecke, gell!?)


@Christian: Naja, aber das overload; ist ja genau das Gegenteil von dem was ich gerne hätte. Ich möchte ja eine Implementierung mit mehreren möglichen Deklarationen, und nicht mehrere Prozedurrümpfe, jeweils für einen Fall gesondert :zwinker:
Oder hab ich dich verstanden Mist?


grüzli,
dizzy

Christian Seehase 20. Mai 2004 00:12

Re: Prozedur-Parameter mit variantem Typ?
 
Moin Dizzy,

nein, Du hast mich nicht mistverstanden ;-)

Das Problem ist nur:
Entweder Du fasst alles in einer, dann entsprechend umfangreichen, Methode zusammen, oder Du teilst es auf spezialisierte Methoden auf.
Letzteres hätte den Vorteil, dass Du übersichtlichere Methoden bekommst, und auch leichter noch Datentypen hinzufügen kannst, soweit erforderlich. Vermutlich wäre diese Variante auch schneller, mit Sicherheit aber leichter zu warten/debuggen.

Nachteil:
Redundanter Code.

Tryer 20. Mai 2004 00:21

Re: Prozedur-Parameter mit variantem Typ?
 
Casting und Pseudocode werden so auch funktionieren. Du brauchst in der Deklaration nicht von Record auf Array umsteigen. Beim Zugriff auf das statische Array wird ja sozusagen direkt auf´s erste Element zugegriffen. Für Records gilt die gleiche Zugriffsweise. Der sicherheit halber würde ich aber vielleicht noch TNumber und die Records als packed deklarieren.

Innerhalb der Get/Set-Routinen solltest Du dann natürlich abhängig vom NumericFormat das ganze in den "richtigen" Datenstrukturen ablegen, aber nach aussen erscheint alles als TNumber.

Die Property an sich ist nichts besonderes:
Canvas.Pixels[X, Y: Integer]
List.Items[Index: Integer]
TStringsList.Value[Name: string] (?)
..
Der Index kann also jegliche Form annehmen (z.B. auch ein TVarNames = (A, B, C, D, E, F, ..), einzige Bedingung ist Schreib-und Lesezugriff als Methode bereitzustellen (ein direkter Feldzugriff auf "FNumber" könnte natürlich nicht zugeordnet werden.

MfG,
Tryer

dizzy 20. Mai 2004 00:30

Re: Prozedur-Parameter mit variantem Typ?
 
Zitat:

Zitat von Christian Seehase
[..] übersichtlichere Methoden
[..] leichter noch Datentypen hinzufügen
[..] auch schneller
[..] leichter zu warten/debuggen

Nachteil:
Redundanter Code.

Ich glaube, du hast mich überzeugt :mrgreen:

Ich lass es dann zunächst so, wie es ist. Das mit den Variablen habe ich mir gerade auch nochmal durch den Kopf gehen lassen: Es wäre natürlich toll ein und den selben Namen für eine Variable mit variierendem Typ zu haben, weil nur ein Typ gleichzeitig vorkommt - nur was täte man damit einem Programmierer an? Man müsste ständig nachhalten, was man vor 1000 Zeilen Code mal dort reingeschrieben hat - und von welchem Typ das ganze war...
Ich werde das prinzipell mal ausprobieren, was Tryer vorschlug (sieht nämlich irgendwie total elegant aus!), aber ob ich das dann durch meine 3tausend Zeilen Code durchziehe weiss ich noch nicht. Zudem hängen an den Datentypen mittlerweile 3 Programme und 3 Klassen (ausser dem Parser) auch mit insgesammt mehreren tausend Zeilen Code dran :? Tja - die Datentypen verwende ich schon etwas länger in ihrer Form als record - weit länger, als der Parser jetzt existiert :) Das kommt dann davon, wen man nicht von vorne herein alles haarklein planen kann... Mist Freizeitprojekte :lol:


Ganz heissen Dank an euch! Und wenn dann doch noch jemandem was dazu einfällt, dann mal immer her damit...

dizzy 20. Mai 2004 00:34

Re: Prozedur-Parameter mit variantem Typ?
 
Zitat:

Zitat von Tryer
Casting und Pseudocode werden so auch funktionieren. Du brauchst in der Deklaration nicht von Record auf Array umsteigen. Beim Zugriff auf das statische Array wird ja sozusagen direkt auf´s erste Element zugegriffen. Für Records gilt die gleiche Zugriffsweise. Der sicherheit halber würde ich aber vielleicht noch TNumber und die Records als packed deklarieren.

Innerhalb der Get/Set-Routinen solltest Du dann natürlich abhängig vom NumericFormat das ganze in den "richtigen" Datenstrukturen ablegen, aber nach aussen erscheint alles als TNumber.

Die Property an sich ist nichts besonderes:
Canvas.Pixels[X, Y: Integer]
List.Items[Index: Integer]
TStringsList.Value[Name: string] (?)
..
Der Index kann also jegliche Form annehmen (z.B. auch ein TVarNames = (A, B, C, D, E, F, ..), einzige Bedingung ist Schreib-und Lesezugriff als Methode bereitzustellen (ein direkter Feldzugriff auf "FNumber" könnte natürlich nicht zugeordnet werden.

MfG,
Tryer

Ei! Grade erst gesehen! Stimmt... Pixels... ja, da hab ich das auch schon mal gesehen *g*. Mich hat der Typ String als Index so verwundert... aber das ist ja mal nett, dass das geht!

Ich glaube, ich komme jetzt dahinter, wie du das meinst. Das sieht echt gut aus! Da muss ich gleich mal ein wenig fummeln gehen :coder:
(Du bist doch noch länger wach, gelle!? ;) )


Dangöö!

dizzy 20. Mai 2004 00:48

Re: Prozedur-Parameter mit variantem Typ?
 
Der Cast tut nicht. (Ungültige Typumwandlung)
SetVariable:
Delphi-Quellcode:
procedure TCQParser.SetVariable(VarName: TVarName; const Value: TNumber);
begin
  case VarName of
    A: case NumberFormat of
         nfReal     : Ar := double(Value);  // dieser Cast geht
         nfComplex  : Ac := TComplex(Value); // der nicht
         nfQuaternion: Aq := TQuat(Value);   // der auch nicht...
    B: . . .
    .
    .
    .
  end;
end;
Was tun? Steh' grad ein wenig wie Ochs vorm Berg, weil SO abwegig hab ich noch nie gecastet :)


\\edit:
So gehts:
Delphi-Quellcode:
type PNumber = ^TNumber;
.
.
.
procedure TCQParser.SetVariable(VarName: TVarName; const Value: PNumber);
begin
  case VarName of
    A:
    case NumberFormat of
      nfReal     : Ar := Value[0];
      nfComplex  : Ac := PComplex(Value)^;
      nfQuaternion: Aq := PQuat(Value)^;
    end;
    B: . . .
    .
    .
    .
  end;
end;
Sieht völlig geil aus :lol: und funzt!
Schade ist nur, dass man jetzt bei der Zuweisung einer Variablen an eine Instanz des Parsers wie folgt vorgehen muss:
Delphi-Quellcode:
var p: TCQParser;
    q: TQuat;

  q.x := pi/2;
  q.y := 0;
  q.z := 0;
  q.w := 0;
  p.Variable[A] := PNumber(@q);
Das heisst, dass der "user" der Klasse auch noch wie wild casten müsste, und dass immer nur Variablen (im Sinne von Delphi-Variablen jetzt) übergeben werden müssen. Einfach eine 1 ist dann nicht mehr möglich.
Aber Abstriche hat man überall, woll!?
Den Cast bei der Zuweisung würde ich gerne aber noch irgendwie los werden. Kann man das irgendwie bewerkstelligen?


Schonmal einen riesen-Dank! Das klappt soweit!! *froi*
dizzy

Christian Seehase 20. Mai 2004 01:26

Re: Prozedur-Parameter mit variantem Typ?
 
Moin Dizzy,

was hältst Du von dieser Idee die Typen "in einem Rutsch" zu deklarieren:

Delphi-Quellcode:
type
  TNumberType = (ntDouble,ntComplex,ntQuad);

  TNumber = record
    ntType : TNumberType;
    x     : double;
    y     : double;
    z     : double;
    w     : double;
  end;
ich hoffe es ist selbsterklärend ;-)

dizzy 20. Mai 2004 01:44

Re: Prozedur-Parameter mit variantem Typ?
 
Zitat:

Zitat von Christian Seehase
Moin Dizzy,
was hältst Du von dieser Idee die Typen "in einem Rutsch" zu deklarieren:
ich hoffe es ist selbsterklärend ;-)

Japp, ist es :)
Hat seinen Reiz! Ich fürchte nur dass es, wie oben schon mal anklang, dafür schon zu spät ist. Die Änderungen die das nach sich ziehen würde wären ziemlich aufwändig. Das Zuweisungsproblem an sich ist ja jetzt gelöst (du hast gepostet während ich editierte...) - es wäre jetzt halt nur noch schön, wenn der Benutzer des Parsers nicht (wie oben) rum-casten müsste. Sobald das ist, bin ich der glücklichste Parser-Schreiber der Welt - und ihr seid schuld :lol:
(btw: könnten sowas die Jedis brauchen?)


ciao,
dizzy :firejump:

Tryer 20. Mai 2004 01:54

Re: Prozedur-Parameter mit variantem Typ?
 
Jo, tut nicht.. sorry, hab mich da etwas vertan.
Das Konstrukt "array [0..0] of xy" macht in manchen Datenstrukturen Sinn (z.B. wenn ich einen Record als Header habe und da am Ende dann eine variable Datenmenge dranhängen möchte), aber hier hilft es absolut nicht weiter.
Über eine "Double-weise" Zuweisung liesse sich was drehen, aber da der Cast ja von aussen nicht klappt ist das ganze eh sinnlos :oops:

Wenn mir noch ne Lösung einfällt melde ich mich,
:duck: MfG, Tryer

[Edit] Ob das mit dem PNumber unter D8 funzen wird wage ich mal zu bezweifeln, ich vermute das sich die Einschränkung da nicht rein auf untypisierte Pointer begrenzen wird. Ein Casting zwischen Datenstrukturen unterschiedlicher Grösse wird vermutlich unzulässig sein (das wäre ja imo genauso "unsicherer Code":roll: wie ein untypisierter Pointer).[/Edit]

dizzy 20. Mai 2004 02:17

Re: Prozedur-Parameter mit variantem Typ?
 
Öh, äh, üh --- Halt! Stop! Klappt doch alles wunderbar!
Nur muss man beim Zuweisen und Auslesen der Variablen in/aus einer Parserinstanz ordentlich rumcasten. Ansonsten funktioniert das voll und ganz! Und die Geschwindigkeit leidet NULL drunter. Für mich sieht das im Moment nach der Lösung aus :)

\\edit: D8 und Casts: Ach weisst du... dann lass ich datt mit D8. Ich bin jetzt so glücklich mit der Lösung... und Win32 ist ja wohl noch nicht tot ;)


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:35 Uhr.
Seite 2 von 3     12 3      

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