Autor |
Beitrag |
Jerk
      
Beiträge: 251
Vista Ultimate, Ubuntu
Turbo Delphi 2006
|
Verfasst: Fr 04.07.08 00:28
Ich bin grade dabei eine Art Werkzeugunit zu erstellen, darunter ist auch eine Procedur namens "XCopy".
Was diese machen soll ist recht simpel, sie soll beim Aufruf also XCopy(@x,@y); die Werte von x und y tauschen, jedoch unabhängig ob x und y string,integer,boolean oder sonstewas sind, weshalb ich den Datentyp Variant gewählt habe.
Erstmal die Procedure
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| procedure XCopy(Var1,Var2 : PVariant); var Buffer : Variant; begin Buffer := Var1^; Var1^ := Var2^; Var2^ := Buffer; end;
...
XCopy(@X,@Y); |
Exception-Klasse EVariantBadVarTypeError mit Meldung 'Invalid variant type'.
Dazu meine Frage, wäre es besser mehrere Überladene Versionen für die einzelnen Datentypen anzufertigen oder wie kann ich das Anstellen.
Bzw. wie kann ich denn die Variable ohne @ übergeben, ähnlich wie bei inc(x,1); ???
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Fr 04.07.08 02:27
Delphi-Quelltext 1:
| procedure XCopy(var Var1,Var2 : PVariant); |
das "var" gibt an, dass nicht die übergebenen werte geändert, sondern die übergebenen variablen verändert (überschrieben) werden sollen...
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Fr 04.07.08 02:34
Also bei mir funzt alles ganz wunderbar. Sowohl die Version mit den Zeigern, als auch die referenzvariablen-Version von Platzwart. Kein Fehler zu sehen.
@Jerk zeig mal genau wie du das aufrufst und wo der Fehler auftritt.
// edit sehe grade, @platzwart: du darfst in deiner Version dann aber natürlich nicht PVariant nehmen sondern Variant selbst. Denn darauf werden ja eh Referenzen übergeben, muss also nicht nochmal "manuell" gemacht werden
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| procedure XCopy(var Var1,Var2 : Variant); var Buffer : Variant; begin Buffer := Var1; Var1 := Var2; Var2 := Buffer; end; |
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
platzwart
      
Beiträge: 1054
Erhaltene Danke: 78
Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
|
Verfasst: Fr 04.07.08 02:43
Tilman hat folgendes geschrieben: |
// edit sehe grade, @platzwart: du darfst in deiner Version dann aber natürlich nicht PVariant nehmen sondern Variant selbst. Denn darauf werden ja eh Referenzen übergeben, muss also nicht nochmal "manuell" gemacht werden
|
korrekt
|
|
Jerk 
      
Beiträge: 251
Vista Ultimate, Ubuntu
Turbo Delphi 2006
|
Verfasst: Fr 04.07.08 03:23
Jo das geht, vielen Dank!!
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 04.07.08 09:12
 Wobei ich noch anmerken möchte, das 'XCpopy' kein guter Name für die Prozedur ist. 'Exchange' wäre besser. Weiterhin baust Du eine nicht unerhebliche Performancebremse ein.
_________________ Na denn, dann. Bis dann, denn.
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Fr 04.07.08 10:17
I wo, Xcopy ist super, wer benutzt denn heute noch M$-DOS ^^
Ich plädiere für "Swap()". Gibts zwar schon, aber könnte man ja vielleicht überladen.
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
Jerk 
      
Beiträge: 251
Vista Ultimate, Ubuntu
Turbo Delphi 2006
|
Verfasst: Mo 07.07.08 22:11
alzaimar hat folgendes geschrieben: | Wobei ich noch anmerken möchte, das 'XCpopy' kein guter Name für die Prozedur ist. 'Exchange' wäre besser. Weiterhin baust Du eine nicht unerhebliche Performancebremse ein. |
Deswegen meine Frage, wäre überladen besser gewesen?
|
|
Grenzgaenger
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 07.07.08 22:54
|
|
Timosch
      
Beiträge: 1314
Debian Squeeze, Win 7 Prof.
D7 Pers
|
Verfasst: Di 08.07.08 16:57
Kann man nicht auch irgendwie Parameter als void oder so deklarieren? Wenn ich SizeOf verwende, kommt z.B. immer als Hilfe "Kein Typ angegeben" oder so...
_________________ If liberty means anything at all, it means the right to tell people what they do not want to hear. - George Orwell
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: Di 08.07.08 17:15
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Di 08.07.08 18:51
Nein, funktioniert nicht. Man kann einen untypisierten Zeiger (Pointer) nicht dereferenzieren. Wohin auch? So ein allgemeingültiger Vertausch-O-Mat kann nicht funktionieren, denn spätestens bei Objekten legt er sich die Karten. Bei einfachen Typen müsste man die Datentypgröße mit angeben und dann mit MoveMemory arbeiten.
_________________ Na denn, dann. Bis dann, denn.
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: Di 08.07.08 21:02
Ich denke auch, es ist ganz interessant um mal zu sehen was so alles möglich ist - aber wirklich zum verwenden eher ungeeignet.
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
jaenicke
      
Beiträge: 19315
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mi 09.07.08 11:09
alzaimar hat folgendes geschrieben: | Nein, funktioniert nicht. Man kann einen untypisierten Zeiger (Pointer) nicht dereferenzieren. Wohin auch? So ein allgemeingültiger Vertausch-O-Mat kann nicht funktionieren, denn spätestens bei Objekten legt er sich die Karten. Bei einfachen Typen müsste man die Datentypgröße mit angeben und dann mit MoveMemory arbeiten. |
Warum eigentlich? Dereferenzieren ist hier ja auch gar nicht nötig. Schließlich sind die Variablen doch im Grunde Zeiger auf das jeweilige Objekt, d.h. wenn ich zwei gleiche Objekte habe (worum es hier ja geht), dann genügt es doch den Zeiger entsprechend auf das jeweils andere Objekt zeigen zu lassen, oder?
Was ich nicht weiß ist, ob das die Referenzcounter durcheinanderbringt, weil ich mir nie angeschaut habe wie die implementiert sind, aber eigentlich werden die ja im Objekt gespeichert und die Anzahl der darauf zeigenden Pointer ändert sich ja nicht. (Bei untypisierten Zugriffen können die Referenzcounter ja nicht aktualisiert werden, das zur Erklärung, weshalb ich darüber nachgedacht habe.) Aber dazu kannst du ja vermutlich was sagen, was da (evtl. falsch) passiert. Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm75.Button1Click(Sender: TObject);
procedure ExchangePointer(var x1, x2: Pointer); var tmp: Pointer; begin tmp := x1; x1 := x2; x2 := tmp; end;
begin ExchangePointer(Pointer(Edit1), Pointer(Edit2)); ShowMessage(Edit2.Text); end; | Funktionieren tut es soweit, es gibt auch keine Abstürze. Mir fielen jetzt auch keine negativen Effekte ein, die sich daraus ergeben könnten.
Für einfache Datentypen dann dazu noch überladene Versionen, dann sollte alles abgedeckt sein.
|
|
|