Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Objekt komplett mit enthaltenden Objekten kopieren (https://www.delphipraxis.net/58182-objekt-komplett-mit-enthaltenden-objekten-kopieren.html)

dizzy 2. Dez 2005 14:42


Objekt komplett mit enthaltenden Objekten kopieren
 
Hi geschätzte Forumler!

Ich zermatere mir grad den Kopf darüber wie ich etwas wie im Titel beschrieben möglichst einfach realisieren kann. Ich poste mal zum besseren Verständnis um was für eine Struktur es sich handelt:
Delphi-Quellcode:
  TGridPoint = class(TObject)
  private
    FPos: TVector;
    FAbove,
    FUnder,
    FLeft,
    FRight: TGridPoint;
  public
    constructor Create(aPosX, aPosY: Single; aAbove, aUnder, aLeft, aRight: TGridPoint);
    property Position : TVector   read FPos  write FPos;
    property PointAbove: TGridPoint read FAbove write FAbove;
    property PointUnder: TGridPoint read FUnder write FUnder;
    property PointLeft : TGridPoint read FLeft write FLeft;
    property PointRight: TGridPoint read FRight write FRight;
  end;

  TGrid = class(TObject)
  private
    FRoot: TGridPoint;
  public
    constructor Create(aSizeX, aSizeY: Single);
  end;
Es geht nun um TGrid: Ein Objekt also, dass ein Gitter enthalten soll, wobei jeder Punkt des Gitters wieder ein Objekt ist, die lediglich über Referenzen untereinander verbunden sind.
Ziel soll es nachher sein soetwas machen zu können:
Delphi-Quellcode:
procedure Foo;
var
  gridA, gridB: TGrid;
begin
  gridA := TGrid.Create(...);
  // irgendwas mit gridA machen
  gridA.CopyInto(gridB);
end;
Nuja, eben letzte Zeile ist so das Dingen. Eine einfache Zuweisung des Pointers ist nicht drin, da ich das Teil unbedingt 2 mal brauche, und sie sollen sich nach dem Kopieren unabhängig voneinander verändern können. Problem dabei ist denke ich, dass die Verweise der TGridPoints untereinander ekelig werden könnten, da sich ja komplett die Adressen ändern werden...
Gibt es da eine möglichst simple Variante das so zu basteln?

Vielen Dank schonmal!
Fabian

Khabarakh 2. Dez 2005 15:10

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
Wenn ich das Problem richtig verstanden habe, sollte es so funktionieren:
Delphi-Quellcode:
function TGridPoint.Assign(Source: TPersistent);
begin
  if Source is TGridPoint then
    with TGridPoint(Source) do
    begin
      Self.Position := Position;
      // Wenn der obere Punkt noch nicht zugewiesen wurde (sonst gäbe es eine hübsche Endlosschleife)
      if (Self.PointAbove = nil) and (PointAbove <> nil) then
      begin
        Self.PointAbove := TGridPoint.Create; // Hier müsstest du noch einen weiteren Konstruktor hinzufügen
        Self.PointAbove.PointUnder := Self;
        Self.PointAbove.Assign(PointAbove);
      end;

      if not Assigned(Self.PointLeft) and Assigned(PointLeft) then
        [...]
    end
  else
    inherited;
end;
[edit] Nein, so gäbe es immer noch eine Endlosschleife *weiternachdenk* [/edit]

[edit2] Das Problem ist wirklich verzwickt *g* . Gerade fällt mir nur ein, das Grid temporär in ein zweidimensionales Array zu speichern (wenn das bei deinem Aufbau der Knoten möglich ist) und daraus wieder das Grid zu erstellen oder mit einem Feld in den zu kopierenden Knoten zu kennzeichnen, ob sie schon kopiert wurden. Bei Letzterem könnte man meine Prozedur von oben mit wenigen Änderungen übernehmen. [/edit2]

dizzy 2. Dez 2005 17:24

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
Hi,
ich habe selbst auch noch ein wenig probiert, und komme lediglich zu ähnlichen Ansätzen wie deinem. Scheint als müsste ich tatsächlich Schritt für Schritt das Kopie-Objekt createn. Au Backe, das wird ne doofe Sache - grad die bidirektionalen Verweise wieder herzustellen. Nicht unmöglich, aber auch nicht toll :stupid:

Falls jemandem noch eine elegantere Variante einfällt...

PS: Die Array-Idee ist so schlecht auch nicht, allerdings müsste ich aus den Verweisen der Punkte Indeces generieren, und umgekehrt nochmal. Davon ab würde das Objekt 2 mal kopiert werden müssen :?

Fabian

Dax 2. Dez 2005 17:33

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
*sich mal an die Aufgabe setz*

Klingt nach einer interessanten Herausforderung.

Dax 2. Dez 2005 18:10

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
So, ich bin auf das hier gekommen:

Delphi-Quellcode:
  TGridPoint = class(TObject)
  private
    FPos: TVector;
    FAbove,
    FUnder,
    FLeft,
    FRight: TGridPoint;



    constructor CreateOnNil;
  public
    constructor Create(aPosX, aPosY: Single; aAbove, aUnder, aLeft, aRight: TGridPoint);
    property Position : TVector   read FPos  write FPos;
    property PointAbove: TGridPoint read FAbove write FAbove;
    property PointUnder: TGridPoint read FUnder write FUnder;
    property PointLeft : TGridPoint read FLeft write FLeft;
    property PointRight: TGridPoint read FRight write FRight;


    function Replicate: TGridPoint;

  end;

{ TGridPoint }

function TGridPoint.Replicate: TGridPoint;
type
  TCloneGridPoint = record
    Point,
    FGridPoint: TGridPoint;
  end;

var
  Cells: array of TCloneGridPoint;

  function CellsIndex(Point: TGridPoint): Integer;
  var i: Integer;
  begin
    Result := -1;
    for i := 0 to High(Cells) do
      if Cells[i].FGridPoint = Point then
      begin
        Result := i;
        Exit;
      end;
  end;

  function CellsContain(Point: TGridPoint): Boolean;
  begin
    Result := CellsIndex(Point) <> -1;
  end;

  function CloneSingleCell(Cell: TGridPoint): TGridPoint;
  begin
    if Cell = nil then
    begin
      Result := nil;
      Exit;
    end;
    if not CellsContain(Cell) then
    begin
      Result := TGridPoint.CreateOnNil;
      Result.Position := Cell.Position;

      SetLength(Cells, Length(Cells)+1);
      Cells[High(Cells)].Point := Result;
      Cells[High(Cells)].FGridPoint := Cell;

      Result.PointAbove := CloneSingleCell(Cell.PointAbove);
      Result.PointUnder := CloneSingleCell(Cell.PointUnder);
      Result.PointLeft := CloneSingleCell(Cell.PointLeft);
      Result.PointRight := CloneSingleCell(Cell.PointRight);
    end
    else
      Result := Cells[CellsIndex(Cell)].Point;
  end;

begin
  Result := CloneSingleCell(Self);
end;

constructor TGridPoint.Create(aPosX, aPosY: Single; aAbove, aUnder, aLeft,
  aRight: TGridPoint);
begin
  FAbove := aAbove;
  FUnder := aUnder;
  FLeft := aLeft;
  FRight := aRight;
  FPos.x := aPosX;
  FPos.y := aPosY;
end;

constructor TGridPoint.CreateOnNil;
begin

end;
dizzy, bitte mal austesten ;)

dizzy 2. Dez 2005 18:43

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
:shock: Das war mal schnell! Muss ich erstmal soweit bauen, dass ich das überhaupt testen KANN ^^. Soweit ich den Code beim Drüberfliegen verstanden habe, sieht das nach einer äusserst interessanten Methode aus. Ich melde mich alsbald zurück :)

Danke dir schon (noch ;)) mal!

Dax 2. Dez 2005 18:47

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
Rekursion ist für Replikation mit Querverbindung unter Kindknoten immer gut geeignet (man fühl ich mich jetzt schlau :mrgreen:)

Aber mal ernsthaft: Darin sehe ich die einzig wirklich benutzbare Möglichkeit ;)

Zitat:

Zitat von dizzy
Danke dir schon (noch ;)) mal!

Wie, noch mal? ^^

dizzy 2. Dez 2005 19:30

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
Verflucht - das tut! Und das tut hervorragend! Sogar ohne Endlosrekursion :zwinker:

Zitat:

Zitat von Dax
Zitat:

Zitat von dizzy
Danke dir schon (noch ;)) mal!

Wie, noch mal? ^^

Ist ja nicht das erste mal, dass du mir mit genialen Einfällen mächtig weitergeholfen hast.


just :love:

Dax 2. Dez 2005 19:33

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
Schön zu wissen, das es funktioniert :)

Vielleicht sollten wir mehr zusammen schreiben, dann könnten deine Programme auch mal fertig werden :zwinker:

dizzy 2. Dez 2005 19:52

Re: Objekt komplett mit enthaltenden Objekten kopieren
 
Zitat:

Zitat von Dax
Schön zu wissen, das es funktioniert :)

Vielleicht sollten wir mehr zusammen schreiben, dann könnten deine Programme auch mal fertig werden :zwinker:

Ey, werd nicht frech :P ...aber Recht hast du mit dem fertig werden *sigh*. Bei dem Projekt zu dem diese Frage hier gehört bin ich jedoch (mal wieder) fest entschlossen es auch fertig zu machen (so weit fertig wie Software werden kann ^^). Ja, auch mit einer Abspeichern-Funktion vor der ich mich immer so erfolgreich drücke 8).


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:56 Uhr.
Seite 1 von 2  1 2      

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