![]() |
Alter Classe neue zuweisen
Ich möchte zwei Classen miteinander vertauschen.
Abhängig von Items.
Delphi-Quellcode:
procedure SWAP(var Value1, Value2: Integer);
var lTemp: integer; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end;
Delphi-Quellcode:
Das geht natürlich nicht weil meine SWAP Function integer erwartet.
// SWAP ITEM
if Item <> FlagFound then begin SWAP(gS[FlagFound], gS[Item]); FlagFound := Item; end; gs aber ein Classe ist. Mit Assign geht's auch nicht .. noch andere Möglichkeiten? Bin mir jetzt nicht sicher ob das der richtige weg wäre. Zumindest meckert der Compiler nicht.
Delphi-Quellcode:
gS[FlagFound] := gS[Item];
gruss |
AW: Alter Classe neue zuweisen
Dann deklarier doch einfach ein Swap für den Klassentyp (hier TMyClass):
Delphi-Quellcode:
procedure SwapMyClass(var Value1, Value2: TMyClass);
var lTemp: TMyClass; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end; |
AW: Alter Classe neue zuweisen
Es ist schon spät, von daher weiß ich nicht, ob ich gerade um die Ecke denke (wenn überhaupt noch ;-))
Delphi-Quellcode:
Aber vermutlich möchtest Du die Inhalte von gS[?] tauschen.
procedure SWAP(var Value1, Value2: TBasisKlasseDerZuTauschendenClassen); // eventuell TObject?
var lTemp: TBasisKlasseDerZuTauschendenClassen; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end; Was genau ist in gS[?] zu finden? FlagFound und Item sind (vermutlich) Angaben für den Index von gS. Würde es mal so probieren:
Delphi-Quellcode:
procedure SWAP(var Value1, Value2: TKlasse_Oder_Typ_gS[Item]);
var lTemp: TKlasse_Oder_Typ_gS[Item]; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end; |
AW: Alter Classe neue zuweisen
Zitat:
![]()
Delphi-Quellcode:
procedure SWAP(var Value1: TNegativeArray; var Value2: TNegativeArray);
var lTemp: TNegativeArray; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end;
Delphi-Quellcode:
SWAP(gS[FlagFound], gS[Item]);
Zitat:
Zitat:
Zitat:
gS[FlagFound] soll alle Eigenschaften inklusive der werte von gS[Item] erhalten. Danch wird FlagFound der Index von Item zugewiesen. Zitat:
gruss |
AW: Alter Classe neue zuweisen
Wenn ich das richtig sehe ist gS[Item] vom Typ TSprite.
Lass bitte bei Swap mal das var weg. Also eher sowas:
Delphi-Quellcode:
Aufruf dann so:
procedure SWAP(Value1, Value2: TSprite);
var lTemp: TSprite; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end;
Delphi-Quellcode:
SWAP(gS[FlagFound], gS[Item]);
Wenn's das auch nicht ist, sollte ich den Rechner ausschalten und mich auf's Ohr hauen ;-) |
AW: Alter Classe neue zuweisen
Zitat:
Eigentlich ist gs schon vom Type TNegativeArray die TSprite Classe wird dort erst generiert.
Delphi-Quellcode:
Fdata : array of TSprite;
jetzt meldet er aber hier ohne Var Parameter Zitat:
Delphi-Quellcode:
Schalte ich den Var Parameter wieder ein kommt diese Meldung
procedure SWAP(Value1, Value2: TSprite);
var lTemp: TSprite; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end; Zitat:
gruss |
AW: Alter Classe neue zuweisen
Du willst aber doch zwei Elemente aus gS vertauschen (die Elemente mit Index FlagFound und Index Item), also zwei TSprite und nicht zwei TNegativeArray.
In gS[FlagFound] soll sich anschließend gS[Item] befinden und in gS[Item] soll sich gS[FlagFound] befinden. Oder hab' ich da was noch nicht recht verstanden. Liege ich falsch, beschreib' bitte mal verbal, was Du erledigen möchtest. Eventuell kommen wir dann weiter. |
AW: Alter Classe neue zuweisen
Nein Zwei identische classen TNegativeArray
definiert als
Delphi-Quellcode:
gs: TNegativeArray;
die TSprite Classen werden in der Classe TNegativeArray erstellt.
Delphi-Quellcode:
Fdata : array of TSprite;
ich möchte jetzt gs einen neuen Index "Item" zu weisen von der Classe TSprite. Die dann alle Eigenschaften von der Classe TNegativeArray und des Arrays von TSprite enthält. gruss |
AW: Alter Classe neue zuweisen
Du definierst
Delphi-Quellcode:
Im Eingangspost schriebst Du
var
gs: TNegativeArray;
Delphi-Quellcode:
gS[FlagFound] := gS[Item];
Das bedeutet meiner Meinung nach, dass Du zwei Elemente des TNegativeArray gS vertauschen möchtest. Stimmt das, oder bin ich gerade auf dem Holzweg? TNegativeArray enthält doch (glaub' ich) 1 bis n Elemente der Klasse TSprite. Oder ist es andersherum, dass TSprite eine Array ist, dass Elemente der Klasse TNegativeArray enthält? |
AW: Alter Classe neue zuweisen
Zitat:
Delphi-Quellcode:
gS[FlagFound] := gS[Item];
gs soll vertauscht werden damit der Inhalt von gs[Item] im gS[FlagFound] enthalten ist. vorher kann ich den Index FlagFound nicht durch den von Item ersetzen. gruss |
AW: Alter Classe neue zuweisen
Das TSprite aus gS[FlagFound] soll sich also nachher in gS[Item] befinden und das aus gS[Item] in gS[FlagFound].
Meiner Meinung nach müsste das mit dem Vorschlag aus Post #5 funktionieren. |
AW: Alter Classe neue zuweisen
Zitat:
und gS[FlagFound] bekommt den Index von Item zugewiesen. Es geht nicht mit der Version im Beitrag 5 warum habe ich daraufhin geantwortet ;)
Delphi-Quellcode:
// SWAP Item
if Item <> FlagFound then begin //SWAP(gS[FlagFound], gS[Item]); gS[FlagFound] := gS[Item]; FlagFound := Item; end; gruss |
AW: Alter Classe neue zuweisen
Irgendwie verstehe ich das nicht und hab' momentan auch keine Idee, was da jetzt nicht funktioniert und warum :-(
Ärgerlich. |
AW: Alter Classe neue zuweisen
Zitat:
Zitat:
Delphi-Quellcode:
SWAP(gS[FlagFound], gS[Item]);
wirft den Fehler. Und den Var-Parameter brauche ich weil sonst nichts zurückgegeben wird. Vielleicht ist ja ein direkter Cast möglich kann es jetzt nur noch nicht testen.
Delphi-Quellcode:
gS[FlagFound] := gS[Item];
gruss |
AW: Alter Classe neue zuweisen
Das sind doch garkeine Var-Parameter drinne:
Delphi-Quellcode:
Hm, was verstehe ich denn hier jetzt nicht?
procedure SWAP(Value1, Value2: TSprite);
var lTemp: TSprite; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end; Ist wohl doch zu spät oder noch zu früh? ;-) |
AW: Alter Classe neue zuweisen
Zitat:
Zitat:
Ach spät :) Ist meine normale Arbeitszeit. gruss |
AW: Alter Classe neue zuweisen
|
AW: Alter Classe neue zuweisen
Zitat:
Werde mich damit mal befassen vielleicht ist was brauchbares dabei. gruss |
AW: Alter Classe neue zuweisen
Hallo,
das ist hier ein Stochern im Nebel. Viel zu wenig Quellcode, mindestens die Definition von TSprite ist hier noch notwendig ... procedure SWAP(Value1, Value2: TSprite); Was ist TSprite, Klasse oder ein Record? Wenn es eine Record ist, muss das var davor, bei einer Klasse nicht, solange in der Methode selbst keine neue Klasse erzeugt wird (Tauschen ist nicht "neu erzeugen") procedure SWAP(var Value1, Value2: TSprite); Die Meldung des Compilers ist genau richtig procedure SWAP(Value1, Value2: TSprite); Value1 und Value2 werden auf dem Stack neu angelegt (Achtung, nicht mit dem Erzeugen von Klassen verwechseln), dann wird der Inhalt der übergebenen Werte in die beiden Stack-Variablen reinkopiert var lTemp: TSprite; begin lTemp := Value1; Value1 := Value2; Value2 := lTemp; end; [DCC Hinweis] uGlobal.pas(144): H2077 Auf 'Value2' zugewiesener Wert wird niemals benutzt [DCC Hinweis] uGlobal.pas(143): H2077 Auf 'Value1' zugewiesener Wert wird niemals benutzt lTemp: noch ein Variable Value1 := Value2; Value2 := lTemp; Wertezuweisung ohne Sinn end; Hier werden Value1,Value2,lTemp wider freigegeben, der Inhalt der Ursprungsvariablen, die an Swap übergeben worden sind, bliebt erhalten. Lösung bei Records procedure SWAP(var Value1, Value2: TSprite); |
AW: Alter Classe neue zuweisen
Zitat:
![]() Mehr geht beim besten willen nicht. gruss |
AW: Alter Classe neue zuweisen
Zitat:
Delphi-Quellcode:
?
function MySwap(var gs:TNegativArray; var FlagFound,Item:integer);
begin gS[FlagFound].assign(gs[item]); FlagFound := Item; end; |
AW: Alter Classe neue zuweisen
Werde ich mal versuchen.. Danke Uwe
gruss |
AW: Alter Classe neue zuweisen
Delphi-Quellcode:
gS[FlagFound].assign(gs[item]);
assign gibt es ja nicht in der Classe.
Delphi-Quellcode:
gruss
procedure Swap(var gs: TNegativeArray; var FlagFound, Item: integer);
|
AW: Alter Classe neue zuweisen
Dann ergänz doch einfach die TSprite-Klasse um diese Methode :)
Da werden letzt endlich ja nur die Eigenschaften und Felder zugewiesen. Muster:
Delphi-Quellcode:
procedure TSprite.Assign(source:TPersistent);
begin if (source is TSprite) then begin field1 := source.field1; : Property1 = source.property1; : end; end; |
AW: Alter Classe neue zuweisen
Zitat:
Muss da jetzt leider Raten ;) Für dich ist das alles einfach.. gruss |
AW: Alter Classe neue zuweisen
Das is nur ein Beispiel, da ich ja die genauen Felder bzw. Eigenschaften der TSprite-Klasse nicht kenne ;)
|
AW: Alter Classe neue zuweisen
Wenn zwei Objekte im Array vertauscht werden sollen, dann müsste es eigentlich folgendermaßen funktionieren:
Delphi-Quellcode:
function Swap(gs:TNegativArray; Index1, Index2:integer);
var lTemp: TObject; begin lTemp:=gs[Index1]; gs[Index1]:=gs[Index2]; gs[Index2]:=lTemp; end; |
AW: Alter Classe neue zuweisen
Zitat:
Es sind keine Objekte im Array sondern 2 Klassen\Classen wie auch immer. gruss |
AW: Alter Classe neue zuweisen
Da es sich bei Dir um TSprite handelt, sollte auch dashier ok sein:
Delphi-Quellcode:
Prinzipiell müsste es gehen, wenn man den kleinsten gemeinsamen Nenner an Stelle von TObject angibt.
lTemp: TSprite;
Wenn Deine Klassen als Vorfahren alle z. B. von TComponent abgeleitet sind, direkt oder auch über mehrere Zwischenstufen, dann könntest Du für lTemp TComponent nehmen. Die Swap-Routine könntest Du dann für den Tausch aller Klassen vom Typ TComponent und deren Nachfolger verwenden. TSprite ist ein Nachfolger von TObject, damit müsste der Tausch eigentlich mit der Routine gelingen. |
AW: Alter Classe neue zuweisen
Zitat:
1) wenn man die Objektzeiger tauschen will, dann mit VAR 2) und will man die Objektinhalte tauschen, dann OHNE, da sich ja die Zeiger nicht ändern Allerdings braucht man beim 2. eventuell einen kompletten zwischen Speicher (z.B. ein drittes Objekt oder ein Stream, in den der Zustand des ganzen Objektes rein serialisiert wird) * entweder man kopiert vom kompletten Objekt die Property/Felder in ein 3. Objekte und dann Objekt 2 in 1 und anschließend Temp in 2 (am Besten wäre es, wenn die Objekte das Assign ordentlich implementiert haben, oder sich serialisieren lassen) * oder man kopiert jedes Property/Feld einzeln und nacheinander, z.B. über eine Swap-Methode |
AW: Alter Classe neue zuweisen
Zitat:
Ich würde diese Methode auch direkt in der Klasse TNegativArray implementieren - zwecks Konsistenz mit TList aber unter dem Namen Exchange:
Delphi-Quellcode:
TNegativeArray = class(TObject)
private Fdata : array of TSprite; FMaxValue: Integer; function getData(index : Integer) : TSprite; inline; procedure setData(index : Integer; aData : TSprite); inline; function GetMaxValue: Integer; procedure SetMaxValue(const Value: Integer); public Constructor Create(aLenght : Integer); Destructor Destroy; override; procedure Exchange(Index1, Index2: Integer); property Data[index: Integer]: TSprite read getData write setData; default; property MaxValue: Integer read GetMaxValue write SetMaxValue; end; ... procedure TNegativeArray.Exchange(Index1, Index2: Integer); var lTemp: TSprite; begin lTemp := Data[Index1]; Data[Index1] := Data[Index2]; Data[Index2] := lTemp; end; |
AW: Alter Classe neue zuweisen
Liste der Anhänge anzeigen (Anzahl: 2)
Oder man löst das alles direkt über Interfaces und hält sich nicht unnötig mit irgendwelchen Klassen oder deren Ableitungen auf. Hier mal nur ein Beispiel wie man das evtl. machen könnte. Geht bestimmt noch einfacher bzw. lässt sich erweitern. Also jetzt nicht festnageln, wenn das evtl. umständlich gelöst wäre. Es soll nur ein Ansatz wie man es auch noch lösen kann.
Delphi-Quellcode:
Ergibt bei mir folgendes Ergebnis:
program SwapSample;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils; type ISwapable = interface ['{57064C48-8737-4A57-937D-64654F1F897C}'] procedure SetA(Value: Integer); procedure SetB(Value: Integer); procedure SwapWith(var AnotherObject: ISwapable); function GetA: Integer; function GetB: Integer; property A: Integer read GetA write SetA; property B: Integer read GetB write SetB; end; TSprite = class(TInterfacedObject, ISwapable) private FIntA: Integer; FIntB: Integer; public constructor Create; function GetA: Integer; function GetB: Integer; procedure SetA(Value: Integer); procedure SetB(Value: Integer); procedure SwapWith(var AnotherObject: ISwapable); end; TOtherClass = class(TInterfacedObject, ISwapable) private FIntA: Integer; FIntB: Integer; public constructor Create; function GetA: Integer; function GetB: Integer; procedure SetA(Value: Integer); procedure SetB(Value: Integer); procedure SwapWith(var AnotherObject: ISwapable); end; { TSprite } constructor TSprite.Create; begin FIntA := Random(100); FIntB := Random(250); end; function TSprite.GetA: Integer; begin Result := FIntA; end; function TSprite.GetB: Integer; begin Result := FIntB; end; procedure TSprite.SetA(Value: Integer); begin if (FIntA <> Value) then FIntA := Value; end; procedure TSprite.SetB(Value: Integer); begin if (FIntB <> Value) then FIntB := Value; end; procedure TSprite.SwapWith(var AnotherObject: ISwapable); var tmpA, tmpB: Integer; begin tmpA := Self.FIntA; tmpB := Self.FIntB; Self.FIntA := AnotherObject.A; Self.FIntB := AnotherObject.B; AnotherObject.A := tmpA; AnotherObject.B := tmpB; end; { TOtherClass } constructor TOtherClass.Create; begin FIntA := Random(100) div 2; FIntB := Random(250) div 2; end; function TOtherClass.GetA: Integer; begin Result := FIntA * 2; end; function TOtherClass.GetB: Integer; begin Result := FIntB * 2; end; procedure TOtherClass.SetA(Value: Integer); var tmp: Integer; begin tmp := Value div 2; if (FIntA <> tmp) then FIntA := tmp; end; procedure TOtherClass.SetB(Value: Integer); var tmp: Integer; begin tmp := Value div 2; if (FIntB <> tmp) then FIntB := tmp; end; procedure TOtherClass.SwapWith(var AnotherObject: ISwapable); var tmpA, tmpB: Integer; begin tmpA := Self.FIntA; tmpB := Self.FIntB; Self.FIntA := AnotherObject.A div 2; Self.FIntB := AnotherObject.B div 2; AnotherObject.A := tmpA; AnotherObject.B := tmpB; end; var MySprite, MyOtherObject: ISwapable; begin try Randomize; MySprite := TSprite.Create; MyOtherObject := TOtherClass.Create; Writeln(Format('MySprite A: %d', [MySprite.A])); Writeln(Format('MySprite B: %d', [MySprite.B])); Writeln(Format('MyOtherObject A: %d', [MyOtherObject.A])); Writeln(Format('MyOtherObject B: %d', [MyOtherObject.B])); Writeln; Writeln('Swapping Objects ...'); MySprite.SwapWith(MyOtherObject); Writeln; Writeln('Objects swapped ...'); Writeln; Writeln(Format('MySprite A: %d', [MySprite.A])); Writeln(Format('MySprite B: %d', [MySprite.B])); Writeln(Format('MyOtherObject A: %d', [MyOtherObject.A])); Writeln(Format('MyOtherObject B: %d', [MyOtherObject.B])); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. Anhang 47288 |
AW: Alter Classe neue zuweisen
Ich habe es jetzt mal so umgesetzt und werde es beobachten ob es das ist was ich mir vorstelle.
Delphi-Quellcode:
Ob damit der komplette Inhalt von TSprite ausgetauscht wird muss ich erst noch prüfen.
if Item <> FlagFound then
begin gS.Swap(FlagFound, Item); //gS[FlagFound] := gS[Item]; FlagFound := Item; end; Wenn jetzt gS[FlagFound] den kompletten Inhalt vom bsp. Papierkorb enthält und gS[Item] den vom Computer dann muss anschließend FlagFound den Inhalt des Computer beinhalten. Hab mal 2 Pics angehängt. (nur als Beispiel) gruss |
AW: Alter Classe neue zuweisen
Zitat:
Es sind definitiv Objekte in deinem Array. Eine Klasse ist immer nur ein Typ. Ein Objekt ist eine konkrete, mit Werten "befüllte" Instanz dieses Typs. Von daher: TSprite => Klasse wenn gs: array of TSprite; dann gs[Index] => Objekt vom Typ TSprite Ein Objekt ist immer das, wo man auch Werte zuweisen kann. Eine Klasse ist das, womit man TSprite.Create() schreibt. (Vereinfacht gesagt.) Und TSprite.Create() erzeugt ein Objekt vom Typ TSprite. Mit einer Klasse definierst du lediglich welche Werte mit was für Namen und mit welchen Funktionen eine Einheit ergeben sollen. Aber in einer Klasse stehen noch keine Werte drin. Sie ist nur ein Stempel sozusagen, mit dem du nachher beliebig viele Objekte des Typs TSprite stempeln kannst, wo dann auch Werte rein geschrieben werden können. Das ist zumindest, wie die Begriffe praktisch überall verwendet werden. |
AW: Alter Classe neue zuweisen
Zitat:
Bitte bedenke das bin ich nicht. Von daher danke für die Richtigstellung, versuche es beim nächsten mal etwas genauer zu beschreiben. ;) Am ende war die Lösung von Uwe Raabe das richtige ;) Danke nochmal dafür. gruss |
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:48 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz