Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Wieso kann man Listenelemente nicht kopieren? (https://www.delphipraxis.net/131708-wieso-kann-man-listenelemente-nicht-kopieren.html)

wonnebeekiwi 29. Mär 2009 14:44


Wieso kann man Listenelemente nicht kopieren?
 
Wieso kann man Listenelemente nicht kopieren?
Ich versuche ein Element aus einer Liste zu kopieren. Wenn ich die kopie veränder, ändert sich das orginal selbst.
Hier mal im extrem Fall:
Delphi-Quellcode:
procedure TElement.xy;
var Kopie: TElement;
begin
  Kopie := Self;
  Kopie.Free;
end;
Das Element ist gelöscht!!!
Das stellt mich echt vor Probleme. Kann mir jemand schlaueres eine Anregung geben, wie ich mit dem Problem fertig werde?
Grüße

Satty67 29. Mär 2009 14:46

Re: Wieso kann man Listenelemente nicht kopieren?
 
Du kopierst nur den Zeiger auf das Element und greifst damit immer auf das gleiche Element zu. Also nix mit kopiert (vom Zeiger abgesehen).

ganz allgemein:
Delphi-Quellcode:
Kopie.Create
Kopie.Assign(self)
Wobei darin enthaltene Objekte durch den Destruktor wohl auch freigegeben werden. Kommt jetzt darauf an, was TElement genau für eine Klasse ist.

wonnebeekiwi 29. Mär 2009 14:57

Re: Wieso kann man Listenelemente nicht kopieren?
 
Danke erstmal ;).
Ich kann die Assign Methode nicht nutzen. Delphi zeigt den Fehler: Unbekannterbezeichner an.
TElement ist von der Klasse TObject (TElement = class(TObject)).
Das mit dem Zeiger hört sich sehr sinnvoll an. Die Delphi Hilfe sagt,ich könne die Assign Methode nur für TCollection nutzen. Wie soll ich das machen?

Andreas L. 29. Mär 2009 14:59

Re: Wieso kann man Listenelemente nicht kopieren?
 
Zitat:

Zitat von wonnebeekiwi
Danke erstmal ;).
Ich kann die Assign Methode nicht nutzen. Delphi zeigt den Fehler: Unbekannterbezeichner an.
TElement ist von der Klasse TObject (TElement = class(TObject)).
Das mit dem Zeiger hört sich sehr sinnvoll an. Die Delphi Hilfe sagt,ich könne die Assign Methode nur für TCollection nutzen. Wie soll ich das machen?

Leite TElement von TPersistent ab.

wonnebeekiwi 29. Mär 2009 15:09

Re: Wieso kann man Listenelemente nicht kopieren?
 
Muss ich die Klasse umdefinieren?
...Das habe ich gerade probiert: TElement=class(TPersistent).
Der Rechner kennt aber kein TPersistent.
Habe ich was falsch verstanden?

Satty67 29. Mär 2009 15:15

Re: Wieso kann man Listenelemente nicht kopieren?
 
uses classes eingetragen?

die OH sollte TPersistent aber finden und dort steht (zumindest bei D5) auch die evtl. zu verwendende Unit

xZise 29. Mär 2009 15:19

Re: Wieso kann man Listenelemente nicht kopieren?
 
Delphi-Referenz durchsuchenTPersistent liegt (wenn ich mich richtig erinnere) in der Unit "Classes". Das heißt du musst diese Unit einbinden.

Und als zweites musst du die Methode "Assign" bzw "AssignTo" überschreiben, damit Delphi auch weiß, was den für Daten übernommen werden müssen. Mal ein kleines Beispiel:
Delphi-Quellcode:
type
  TAssignBeispiel = class(TPersistent)
  private
    FEineZahl : Integer;

    procedure AssignTo(Dest: TPersistent);
  public
    property EineZahl : Integer read FEineZahl write FEineZahl;

    procedure Assign(Source: TPersistent); override;
  end;

[...]

procedure TAssignBeispiel.AssignTo(Dest: TPersistent);
begin
  if Dest is TAssignBeispiel then
    TAssignBeispiel(Dest).FEineZahl := Self.FEineZahl
  else
    inherited;
end;

procedure TAssignBeispiel.Assign(Source: TPersistent);
begin
  if Source is TAssignBeispiel then
    Self.FEineZahl := TAssignBeispiel(Source).FEineZahl
  else
    inherited;
end;
MfG
xZise

PS: Mist da war jemand schneller...

[edit]AssignTo + else-Zweig(e)[/edit]

jbg 29. Mär 2009 15:20

Re: Wieso kann man Listenelemente nicht kopieren?
 
Zitat:

Zitat von Andreas L.
Leite TElement von TPersistent ab.

Das reicht nicht. Er muss auch noch die Assign-Methode für TElement umschreiben, denn sonst kommt nur "TElement kann nicht zu TElement zugewiesen werden".

wonnebeekiwi 29. Mär 2009 15:27

Re: Wieso kann man Listenelemente nicht kopieren?
 
Ich Idiot habe natürlich die uses deklaration vergessen.:wall:
Zeigt keine Fehler mehr an.... muss das Programm aber nochmal überarbeiten weil ich jetzt Errors habe.
Da kommt tatsächlich: "TElement kann nicht zu TElement zugewiesen werden".

xZise 29. Mär 2009 15:31

Re: Wieso kann man Listenelemente nicht kopieren?
 
Naja wie gesagt ;) Assign überschreiben (AssignTo ist imho nur optional)
Zitat:

Zitat von xZise
[...]Und als zweites musst du die Methode "Assign" bzw "AssignTo" überschreiben, damit Delphi auch weiß, was den für Daten übernommen werden müssen. Mal ein kleines Beispiel:
Delphi-Quellcode:
type
  TAssignBeispiel = class(TPersistent)
  private
    FEineZahl : Integer;

    procedure AssignTo(Dest: TPersistent);
  public
    property EineZahl : Integer read FEineZahl write FEineZahl;

    procedure Assign(Source: TPersistent); override;
  end;

[...]

procedure TAssignBeispiel.AssignTo(Dest: TPersistent);
begin
  if Dest is TAssignBeispiel then
    TAssignBeispiel(Dest).FEineZahl := Self.FEineZahl
  else
    inherited;
end;

procedure TAssignBeispiel.Assign(Source: TPersistent);
begin
  if Source is TAssignBeispiel then
    Self.FEineZahl := TAssignBeispiel(Source).FEineZahl
  else
    inherited;
end;
[...]

Wenn Source oder Dest nicht ein Objekt die von TAssignBeispiel oder dessen Nachfahren abgeleitet ist, wird die standardmethode (die von Persistent) aufgerufen die einen Fehler verursachen wird. Somit bist du eigentlich immer auf der sicheren Seite ;)

MfG
xZise

wonnebeekiwi 29. Mär 2009 15:45

Re: Wieso kann man Listenelemente nicht kopieren?
 
OK :D... Das läuft jetzt.
Hat jemand irgenteine Idee wo plötzlich Access Violations herkommen können?
Bei Sachen die vorher schon liefen?
Gibt es nennenswerte Unterschiede zwischen TObject und TPersistent die soetwas beeinflussen können?

Andreas L. 29. Mär 2009 15:47

Re: Wieso kann man Listenelemente nicht kopieren?
 
Zitat:

Zitat von jbg
Zitat:

Zitat von Andreas L.
Leite TElement von TPersistent ab.

Das reicht nicht. Er muss auch noch die Assign-Methode für TElement umschreiben, denn sonst kommt nur "TElement kann nicht zu TElement zugewiesen werden".

Naja, da kommt man mit ein bisschen nachdenken auch selber drauf. Und in der Hilfe stehts auch:

Zitat:

In den meisten Anwendungen wird Assign überschrieben, um die Zuweisung von Eigenschaften aus ähnlichen Objekten vorzunehmen. Wenn das Zielobjekt die Zuweisung von Eigenschaften aus Source nicht behandeln kann, rufen Sie beim Überschreiben von Assign die geerbte Methode auf.
Zitat:

OK :D... Das läuft jetzt.
Hat jemand irgenteine Idee wo plötzlich Access Violations herkommen können?
Bei Sachen die vorher schon liefen?
Gibt es nennenswerte Unterschiede zwischen TObject und TPersistent die soetwas beeinflussen können?
Wo bleibt der Debugger stehen? Vermutlich greifst du auf ein noch nicht erstelltes Objekt zu. Poste dochmal deine Klasse.

wonnebeekiwi 29. Mär 2009 15:58

Re: Wieso kann man Listenelemente nicht kopieren?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Delphi-Quellcode:
procedure TForm1.BaumgraphAnzeigen (Baum: TAVLBaum; Tiefe,X,DX: integer);
var Text: string;
    XPos,YPos: integer;
begin
  if not Baum.Leer then
    begin
      DX := DX div 2;
      XPos := X;
      YPos := Tiefe*40 + 20;
      Text := baum.Wurzel.toString;
      ImBaum.Canvas.Ellipse (XPos-10,YPos-5,XPos+24,YPos+15);
      ImBaum.Canvas.TextOut (XPos,YPos-3,Text);
      if not baum.rechts.Leer
      then begin
        ImBaum.Canvas.MoveTo (XPos+7,YPos+15);
        ImBaum.Canvas.LineTo (XPos+7+DX,YPos+40);
      end;
      BaumGraphAnzeigen (baum.rechts,Tiefe+1,X+DX,DX);
      if not baum.links.Leer
      then begin
        ImBaum.Canvas.MoveTo (XPos+7,YPos+15);
        ImBaum.Canvas.LineTo (XPos+7-DX,YPos+40);
      end;
      BaumGraphAnzeigen (baum.links,Tiefe+1,X-DX,DX);
    end;
end;
Der debugger zeigt mir diese Zeile an: Text := baum.Wurzel.toString;
Die Klasse sieht so aus:
Delphi-Quellcode:
type

  TAVLBaum = class(TPersistent)

  private

  public
    Wurzel : TItem;
    Balance: Integer;
    links: TAVLBaum;
    rechts: TAVLBaum;
    constructor create();overload;
    constructor create(Werte: String);overload;
    constructor create(pItem: TItem);overload;
    function KntnFinden(pItem: TItem): Boolean;
    function Hoehe(): Integer;
    function toString():String;
    function Leer():Boolean;
    function KntnEinfuegen(pItem: TItem):boolean;
    procedure Assign(Source: TPersistent);override;
    procedure AssignTo(Dest: TPersistent);override;
    procedure Sortieren;
    procedure LLDrehung;
    procedure LRDrehung;
    procedure RRDrehung;
    procedure RLDrehung;  

end;
Vorher lief das Programm genau so. An den Elementen die ich erstelle hab ich nicht mehr rumgepfuscht.
Im Anhang ist alles.

Andreas L. 29. Mär 2009 18:24

Re: Wieso kann man Listenelemente nicht kopieren?
 
Ich würde mal sagen das die Eigenschaft Wurzel (ein Objekt) von Baum nicht erstellt wurde. Zeig doch mal den constructor von TAVLBaum.

wonnebeekiwi 29. Mär 2009 20:54

Re: Wieso kann man Listenelemente nicht kopieren?
 
constructor TAVLBaum.create;
begin
Wurzel := nil;
Balance := 0;
end;

Andreas L. 29. Mär 2009 20:57

Re: Wieso kann man Listenelemente nicht kopieren?
 
Ich weiß ja nicht was genau TItem (Wurzel) ist, aber probier mal das:
Delphi-Quellcode:
constructor TAVLBaum.create;
begin
  Wurzel := TItem.Create;
  Balance := 0;
end;

wonnebeekiwi 29. Mär 2009 21:01

Re: Wieso kann man Listenelemente nicht kopieren?
 
TItem ist nur eine Puffer Klasse und Leitet auf TDaten weiter. Die Methoden sind alle abstrakt. Wenn ich das so implementiere kommt der Abstract Error.


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