Autor Beitrag
Jerk
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 251

Vista Ultimate, Ubuntu
Turbo Delphi 2006
BeitragVerfasst: 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
ausblenden 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;

...
// Aufruf:

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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Fr 04.07.08 02:27 
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: 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 ;)

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1054
Erhaltene Danke: 78

Win 7, Ubuntu 9.10
Delphi 2007 Pro, C++, Qt
BeitragVerfasst: Fr 04.07.08 02:43 
user profile iconTilman 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 251

Vista Ultimate, Ubuntu
Turbo Delphi 2006
BeitragVerfasst: Fr 04.07.08 03:23 
Jo das geht, vielen Dank!!
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Fr 04.07.08 09:12 
:mahn: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 251

Vista Ultimate, Ubuntu
Turbo Delphi 2006
BeitragVerfasst: Mo 07.07.08 22:11 
user profile iconalzaimar hat folgendes geschrieben:
:mahn: 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



BeitragVerfasst: Mo 07.07.08 22:54 
user profile iconalzaimar hat folgendes geschrieben:
:mahn: 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.


geb dir recht XCopy ist Kacke.. das heisst dass man die zwei elemente irgendwo hin kopieren möcht, was die procedure allerdings nicht macht ... sondern sie vertauscht die werte ... :eyecrazy:

aber um zu variant zurückzukommen, weiss zwar nicht, wie du auf den trichter kommst, aber die umsetzung ist reichlich dämlich... nimm lieber 'n paar funktionen/proceduren überlade sie und optimiere darin den code ... dann hast du was ordentliches :-)
Timosch
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 1314

Debian Squeeze, Win 7 Prof.
D7 Pers
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: Di 08.07.08 17:15 
user profile iconTimosch hat folgendes geschrieben:
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...

ausblenden Delphi-Quelltext
1:
procedure Exchange(var Var1, Var2);					

Das Problem dabei ist, dass du dann die beiden Variablen nicht mehr wirklich austauschen kannst, weil du ja keinen Typ hast, den du als Puffer verwenden kannst. Es sei denn, du willst nur die Adressen austauschen:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
procedure Exchange(var Var1, Var2);
var Buffer: Pointer;
begin
  Buffer := @Var1;
  Var2 := Var1;
  Var1 := Buffer^;
end;

Ich hab keine Ahnung, ob das funktioniert ;)
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19315
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mi 09.07.08 11:09 
user profile iconalzaimar 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.
ausblenden 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.