Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Objekt kopieren (https://www.delphipraxis.net/92698-objekt-kopieren.html)

Luckie 24. Mai 2007 15:57


Objekt kopieren
 
Ichhabe das Problemm, dass ich ein Objekt kopieren muss. Ich habe auch schon im Forum gesucht und Muetze1s Methode mit dem Copy-Constructor gewählt:
Delphi-Quellcode:
constructor TPageCollection.Create(pc: TPageCollection);
begin
  inherited Create;
  FInnerList := TList.Create;
  FInnerList.Assign(pc.FInnerList);
  FPageParent := pc.FPageParent;
  FPageOptions := pc.FPageOptions;
  FOnProgress := pc.FOnProgress;
  FOnSaveFinish := pc.FOnSaveFinish;
  FOnLoadFinish := pc.FOnLoadFinish;
end;
Und der Aufruf:
Delphi-Quellcode:
procedure TFotoBook.DisplayDoublePage(PageIndex: Integer; ScaleFactor: Double);
var
  TempPC: TPageCollection;
  TempLeftPage: TImageEnVect;
  TempRightPage: TImageEnVect;
begin
  TempPC := TPageCollection.Create(FPageCollection);
  if PageIndex = -1 then
    Inc(PageIndex);

  if (not Odd(PageIndex)) and (PageIndex <> 0) then
    Inc(PageIndex);
  // Alles unsichtbar machen, sonst funktio0niert Update nicht
  if Assigned(LeftPage) then
  begin
    LeftPage.Visible := False;
  end;
  if Assigned(RightPage) then
  begin
    RightPage.Visible := False;
  end;

  if (PageIndex = 0) or (PageIndex = -1) then
  begin
    LeftPage := nil;
    TempLeftPage := nil;
  end
  else
  begin
    LeftPage := FPageCollection.Items[PageIndex];
    TempLeftPage := TempPC.Items[PageIndex];
    TempLeftPage.Visible := False;
  end;
  if Assigned(TempLeftPage) then
  begin
    TempLeftPage.Parent := PageParent;
    TempLeftPage.ScrollBars := ssNone;
    TempLeftPage.UnSelAllObjects;
    TempLeftPage.LayersCurrent := 0;
    ScalePage(TempLeftPage, ScaleFactor);
    TempLeftPage.Left := PageParent.Width div 2 - TempLeftPage.Width - PAGEGAP div 2;
    TempLeftPage.Top := PageParent.Height div 2 - TempLeftPage.Height div 2;
    TempLeftPage.Visible := True;
  end;

  if (PageIndex > 0) and not (FPageCollection.Count < 0) then
    Inc(PageIndex);

  if PageIndex < FPageCollection.Count then
  begin
    RightPage := FPageCollection.Items[PageIndex];
    TempRightPage := TempPC.Items[PageIndex];
  end
  else
  begin
    RightPage := nil;
    TempRightPage := nil;
  end;
  if Assigned(TempRightPage) then
  begin
    TempRightPage.Parent := PageParent;
    TempRightPage.ScrollBars := ssNone;
    TempRightPage.UnSelAllObjects;
    TempRightPage.LayersCurrent := 0;
    ScalePage(TempRightPage, ScaleFactor);
    TempRightPage.Left := PageParent.Width div 2 + PAGEGAP div 2;
    TempRightPage.Top := PageParent.Height div 2 - TempRightPage.Height div 2;
    TempRightPage.Visible := True;
  end;
end;
Nur leider wird doch keine Kopie erzeugt, so dass sich die Änderungen ScalePage doch wieder auf die Originale auswirken und das darf nicht sein. Wo liegt hier der Fehler oder was mache ich falsch?

Udontknow 24. Mai 2007 17:11

Re: Objekt kopieren
 
Hallo!

Ohne jetzt die zweite Prozedur richtig verstanden zu haben: Im Konstruktor rufst du ja FInnerList.Assign auf. Wie ist FInnerlist.Assign definiert? Eventuell kopierst du hier nur die Zeiger der Objekte von einer Liste in die andere...

Edit:Ist ein TList-Objekt, ergo nur Zeiger damit kopiert... :)

Cu,
Udontknow

Luckie 25. Mai 2007 08:45

Re: Objekt kopieren
 
Mist und wie mache ich das dann?

alzaimar 25. Mai 2007 08:54

Re: Objekt kopieren
 
Natürlich, indem Du die einzelnen Elemente der Liste klonst. Es gibt ja die Eigenschaft Assign, die Du für die Listen-Elemente überschreiben könntest. Oder Du überschreibst die 'Assign'-Methode der Liste und erstellst Kopien.

Wir leiten unsere Objekte nicht von TObject ab, sondern von einem Nachfahren von TObject, dem wir dann eigene Grundfunktionalität beibringen. Eine davon ist die Clone-Methode (Funktion). Sie liefert eine exakte Kopie des Objektes. Nur das Objekt selbst weiss ja am Besten, wie es sich reproduziert (da würdest Du dir auch nicht reinreden lassen :lol: )

Eine Collection kann sich dann sehr einfach klonen:
Delphi-Quellcode:
Function TMyCollection.Clone : TMyCollection;
Var
  i : Cardinal;

Begin
  Result := TMyCollection.Create;
//  <Copy Attributes>
  For i:=0 to Count- 1 do
    Result.Add (Items[i].Clone);
End;
Eine weitere Möglichkeit ist es, die Klasse von TPersistent abzuleiten, um dann die Reader und Writer Methoden zu erweitern. Dann kannst Du eine Kopie anlegen, indem du das Quellobjekt in einen Stream schreibst, und dann in die Kopie reinlädst.

Luckie 25. Mai 2007 09:08

Re: Objekt kopieren
 
Ach du meine Güte ist das kompliziert. :roll: Na ja gut, dann werde ich mir das mal angucken. Ich arbeite hier übrigens mit dem BDS2006, falls das weiterhilft.

alzaimar 25. Mai 2007 09:12

Re: Objekt kopieren
 
Nö. Auch nicht komplizierter, als bei Off-Topic Posts einzugreifen, hinrlose Beiträge zu löschen, ausgewogen zu moderieren und BDS 2006 zu bedienen.

Ich präferiere selbstgefrickeltes, weswegen ich die Clone-Variante implementiert habe. Ich denke aber, mit TPersistent und eín paar Stunden reinfriemeln kommst Du klar. Ist eine ziemlich coole Angelegenheit.

Udontknow 25. Mai 2007 09:25

Re: Objekt kopieren
 
Ein anderer Weg:

Ich implementiere bei vielen Objekten die Routinen LoadFromStream & SaveToStream. Die kann man dann natürlich hervorragend nutzen, um mittels MemoryStream ein Assign zu implementieren...

Cu,
Udontknow

Luckie 25. Mai 2007 10:10

Re: Objekt kopieren
 
Mein Problem ist, ich habe in einer Liste Komponenten vom Typ TImage. Diese werden jetzt auf der Form dargestellt. Um sie aber darstellen zu können, müssen sie erst noch entsprechend skaliert werden. Wenn ich diese TImage-Komponenten jetzt aber skaliere, sind sie dann auch in der Liste skaliert. Das heißt beim nächsten Anzeigen, werden sie noch mal skaliert, so dass sie immer kleiner werden und nicht nur das, in der Liste sollen sie natürlich in ihrer original Größe verbleiben. Was aber natürlcih nicht der Fall ist, da ich eben nur mit Zeigern arbeite.

Jetzt dachte ich mir, ich kopiere die Liste mit den Komponenten, skaliere sie und zeige sie an, so dass die original Komponenten unberührt davon bleiben. Soweit der Plan. Aber an der Ausführung hapert es eben noch etwas. ;)

alzaimar 25. Mai 2007 10:13

Re: Objekt kopieren
 
Das verstehe, wer will. Wozu willst Du die Images skalieren? Reicht es nicht, zu wissen, wie groß sie werden würden? Das sollte über ein Array of TRect doch gut zu machen sein...

Luckie 25. Mai 2007 10:25

Re: Objekt kopieren
 
Ganz einfach. Das Image hat Din-A4 Größe oder was auch immer. Das kann ich natürlich nicht auf dem Bildschirm darstellen, weil zu groß. Deswegen muss ich es runterskalieren. Da die Images aber Objekte in einer Liste sind, verändere ich sie für immer, wenn ich sie anzeige und das soll / darf nicht sein.

Ich habe es jetzt so gelöst, dass ich sie mit der gleichen Funktion wieder zurückskaliere. Nicht schön, aber geht. ;)

Tormentor32 25. Mai 2007 10:28

Re: Objekt kopieren
 
Also wenn ich ein Bild habe, das ich irgendwie modifiziere, dann mach ich das so, dass ich einen Buffer habe (TBitmap) wo das Original noch drauf ist. Weiß nicht ob das in dein Programm reinpasst...

Klaus01 25. Mai 2007 10:29

Re: Objekt kopieren
 
Zitat:

Zitat von Luckie
Ich habe es jetzt so gelöst, dass ich sie mit der gleichen Funktion wieder zurückskaliere. Nicht schön, aber geht. ;)

Ist das hin- und her skalieren denn nicht verlustbehaftet?
Beim Runterskalieren gehen Bildinformationen verloren - die
beim Hochskalieren nicht wieder zurückgewonnen werden können.

Grüße
Klaus

Luke_83 25. Mai 2007 10:31

Re: Objekt kopieren
 
Hallo probier das doch mal mit Image1.Stretch:=True; aus. vom Typ TImage.
Vorher musst du halt noch die Breite und Höhe des Images festlegen.
Image1.Width=300; Image1.Height=300; Als Beispiel

Luckie 25. Mai 2007 10:38

Re: Objekt kopieren
 
Zitat:

Zitat von Klaus01
Ist das hin- und her skalieren denn nicht verlustbehaftet?

Äh nein. Es ist keine richtige TImage-Komponente sondern, ein klein wenig anderes. ;)

shmia 25. Mai 2007 13:05

Re: Objekt kopieren
 
Das Kopieren von Objekten findet über die Methode Assign statt!
Dazu muss das Zielobjekt von TPersistent abgeleitet sein.

Die Assign-Methode hat immer folgenden Aufbau:
Delphi-Quellcode:
procedure TVerpackung.Assign(Source: TPersistent);
begin
   if Source is TVerpackung then
   begin
      FIdVerp       := TVerpackung(Source).IdVerp;
      FBezeichnung  := TVerpackung(Source).Bezeichnung;
      FVLength      := TVerpackung(Source).VLength;
      FVHeight      := TVerpackung(Source).VHeight;
      FVWidth       := TVerpackung(Source).VWidth;
      FTara         := TVerpackung(Source).Tara;
      FPicture.Assign(Source); // Unterobjekt kopieren
      ...
   end
   else
      // Ganz wichtig:
      // wenn ich die Klasse von "Source" nicht kenne,
      // dann immer inherited aufrufen
      // Könnte sein, dass ein Parentklasse die Zuweisung vornehmen kann
      // falls nicht, hat die VCL noch einen Supertrick in der Hinterhand
      // es wird die Methode AssignTo aufgerufen
      // falls dies auch fehlschlägt, gibt's ein Exception
      inherited;
end;
Der Copy-Constructor ist der schnelle Ersatz für folgenden Code:
Delphi-Quellcode:
objA := TEinObjekt.Create;
objA.Assign(objB);
Der Copy-Constructor macht dann Sinn, wenn in .Create viele Properties zugewiesen werden,
nur um dann in .Assign überbügelt zu werden.
Ganz allgemein ist aber die Assign-Methode wertvoller, da mit ihr auch Objekte unterschiedlicher Klassen
kopiert werden können.

Wenn ein Objekt UnterObjekte hat, dann gibt es zwei Varianten:
1.) nur Hauptobjekt wird kopiert. Bei den Unterobjekten werden nur Referenzen kopiert (2 Zeiger auf's gleiche Objekt)
2.) "Deep-Copy": auch die Unterobjekte werden sauber über Assign kopiert. Alle Objekte sind nun völlig unabhängig voneinander.

Delphi-Quellcode:
constructor TPageCollection.Create(pc: TPageCollection);
begin
  inherited Create;
  FInnerList := TList.Create;
  // die TList-Klasse weiss nicht, dass seine Items Objekte sind
  // also wird hier kein "Deep-Copy" ausgeführt
  FInnerList.Assign(pc.FInnerList);
Es wäre nun zu prüfen, ob TObjectList.Assign einen Depp-Copy ausführt.

alzaimar 25. Mai 2007 13:14

Re: Objekt kopieren
 
Hi shmia, siehe meinen Beitrag #4 (1. Zeile). Aber Du hast es wunderbar erklärt :thumb:

Udontknow 25. Mai 2007 13:28

Re: Objekt kopieren
 
Zitat:

Zitat von shmia
Es wäre nun zu prüfen, ob TObjectList.Assign einen Depp-Copy ausführt.

Ich denke, daß kann man verneinen. Eine ObjectList weiss ja nur, daß es sich um Objekte handelt, hat aber keine Ahnung, wie sie diese nun klonen soll. Ansonsten müsste es ja bereits in TObjekt eine als virtuell deklarierte Methode geben, die TObjectList dann ansteuern könnte.

Cu,
Udontknow

Luckie 30. Mai 2007 13:05

Re: Objekt kopieren
 
Ich brauche jetzt doch eine Kopie der Objekte in der Collection. Deswegen habe ich alzaimars Clone-Methode versicht zu implementieren:
Zitat:

Zitat von alzaimar
Delphi-Quellcode:
Function TMyCollection.Clone : TMyCollection;
Var
  i : Cardinal;

Begin
  Result := TMyCollection.Create;
//  <Copy Attributes>
  For i:=0 to Count- 1 do
    Result.Add (Items[i].Clone);
End;

Allerdings sagt er mir in Zeile 9, dass er die Methode Clone nicht kennt. Ist ja auch klar, das ist ja eine Methode von TMyCollection und nicht von Items. Wie geht denn das jetzt weiter? Muss ich die Items selber um die Clone-Methode erweitern? Und wenn ja, wie sieht das aus?

CCRDude 30. Mai 2007 13:21

Re: Objekt kopieren
 
Ist Assign (wie zuvor von shmia geschrieben) nicht eine notwendige Funktion für jedes TCollectionItem (was ja imho von TPersist kommt)?
Sprich:
Delphi-Quellcode:
For i := 0 to Pred(Count)
 do Result.Add.Assign(Items[i]);
Vorausgesetzt Dein Assign dort funktioniert vernünftig natürlich ;)

Luckie 30. Mai 2007 13:29

Re: Objekt kopieren
 
So wie ich ihn verstanden habe sollte man seine Methode benutzen können um Objekte vom Typ TObject kopieren zu können.

Was meinst du mit:
Zitat:

Zitat von CCRDude
Vorausgesetzt Dein Assign dort funktioniert vernünftig natürlich ;)

Müsste ich die auch noch implementieren in deinem Fall? Und wenn ja, wie müsste sie aussehen?

CCRDude 30. Mai 2007 14:01

Re: Objekt kopieren
 
Weil man bei Collections soviel tippen muss (eben auch das Assign), hatte ich mir ja das hier gebastelt ;)

Ein Beispiel, weil ein Assign zu implementieren ist, hat shmia ja in Post #15 stehen (in obigem Link ebenfalls eins). Die "Herausforderung" bei Collections ist da halt immer, daß man, wenn man neue Properties hinzufügt, gerne mal vergisst, auch das Assign zu aktualisieren - dort musst Du halt selber von Hand eine Kopie jeder kopiergewünschten Eigenschaft anlegen (das automatisch machen zu lassen kann imho nicht funktionieren, da es z.B. bei Zeigern auf Objekten je nach Code drumherum darauf ankommen würde, ob man etwa eine TStringList ebenfalls mit Assign auf die neue kopiert, oder nur den Zeiger selber kopiert, wenn er etwa auf ein spezielles externes Objekt zeigt).

Warum alzaimar da jetzt eine zusätzliche "Clone"-Methode hat, kann ich mir nur so halb vorstellen, da sie halt auch nicht irgendwie automatisierter laufen kann (imho), und zudem genau dasselbe erledigen soll, was Assign macht - nur daß der Aufruf (Rückgabewert & Parameter) vertauscht ist.

alzaimar 30. Mai 2007 14:13

Re: Objekt kopieren
 
Zitat:

Zitat von CCRDude
Warum alzaimar da jetzt eine zusätzliche "Clone"-Methode hat, kann ich mir nur so halb vorstellen

Weil ich nicht alles von TPersistent ableite, siehe auch Beitrag #16 und #4.

Luckie 30. Mai 2007 14:16

Re: Objekt kopieren
 
Puh, ich steige da nicht mehr durch. :wall:

Delphi-Quellcode:
TPageCollection = Class(TObject);
  private
    FInnerList: TList;
    x: Double;
    // ...;
    // ...;
  public
    procedure Add;
    // ...;
    // ...;
end;

procedure TPageCollection.Add(Item: TImageEnVect);
begin
  FinnerList.Add(Item);
end;
So sieht meine Klasse aus. Und davon brauche ich eine Kopie mitsamt der inneren Liste. Was muss ich jetzt konkret wie und wo implementieren, damit man davon eine Kopie erstellen kann?

Noinini 30. Mai 2007 14:48

Re: Objekt kopieren
 
Leider kennen die TImages keine eigene Assign-Methode, von daher müsstest Du auch das Kopieren der Eigenschaften Deiner Images von Hand machen. Am Einfachsten wäre es natürlich, wenn Du anstatt einer TList als innerList eine TImagelist verwendest, die kann das nämlich von alleine.
Wenn Du Dir genau ansehen willst, was Du "von Hand" machen musst, um die TList zu kopieren, dann solltest Du Dir das TImagelist.Assign mal ansehen, das könntest Du dann relativ einfach für Deine Liste übernehmen.

Udontknow 30. Mai 2007 14:51

Re: Objekt kopieren
 
Zitat:

Zitat von Luckie
Ich brauche jetzt doch eine Kopie der Objekte in der Collection. Deswegen habe ich alzaimars Clone-Methode versicht zu implementieren:
Zitat:

Zitat von alzaimar
Delphi-Quellcode:
Function TMyCollection.Clone : TMyCollection;
Var
  i : Cardinal;

Begin
  Result := TMyCollection.Create;
//  <Copy Attributes>
  For i:=0 to Count- 1 do
    Result.Add (Items[i].Clone);
End;

Allerdings sagt er mir in Zeile 9, dass er die Methode Clone nicht kennt. Ist ja auch klar, das ist ja eine Methode von TMyCollection und nicht von Items. Wie geht denn das jetzt weiter? Muss ich die Items selber um die Clone-Methode erweitern? Und wenn ja, wie sieht das aus?

Du meinst sicherlich CollectionItem anstelle TMyCollection? Für die Item-Klasse musst du ja ebenso eine Clone-Routine implementieren. Dann castest du einfach auf TMyCollectionItem, da es sich hierbei ja um Instanzen dieser Klasse handelt.

Delphi-Quellcode:
Function TMyCollection.Clone : TMyCollection;
Var
  i : Cardinal;

Begin
  Result := TMyCollection.Create;
//  <Copy Attributes>
  For i:=0 to Count- 1 do
    Result.Add (TMyCollectionItem(Items[i]).Clone);
End;
Cu,
Udontknow

Luckie 30. Mai 2007 14:53

Re: Objekt kopieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
@Udontknow: Meine Item-Klasse ist vom Typ TList:
Delphi-Quellcode:
TPageCollection = Class(TObject);
  private
    FInnerList: TList;
    x: Double;
    // ...;
    // ...;
  public
    procedure Add;
    // ...;
    // ...;
end;
oder meinst du den Typ der Objekte in der Liste? Die sind vom Typ TImageEnvect (so was wie ein TImage) und kennt die Methode Assign (falls das hilft).

Lösen wir uns mal von dem TImage. Ich habe eben mal schnell eine Demo erstellt:
Delphi-Quellcode:
unit Adressen;

interface

uses
  Classes;

type
  TKontakt = class(TObject)
  private
    FName: String;
    FAlter: Integer;
    function GetAlter: Integer;
    function GetName: String;
    procedure SetAlter(const Value: Integer);
    procedure SetName(const Value: String);
  public
    property Name: String read GetName write SetName;
    property Alter: Integer read GetAlter write SetAlter;
  end;

  TKontaktCollection = class(TObject)
  private
    FInnerList: TList;
    function GetItem(Index: Integer): TKontakt;
    procedure SetItem(Index: Integer; const Value: TKontakt);
  public
    constructor Create;
    destructor Destroy; override;
    procedure Add(Item: TKontakt);
    function Count: Integer;
    property Items[Index: Integer]: TKOntakt read GetItem write SetItem;
  end;

implementation

{ TKontakt }

function TKontakt.GetAlter: Integer;
begin
  Result := FAlter;
end;

function TKontakt.GetName: String;
begin
  Result := FName;
end;

procedure TKontakt.SetAlter(const Value: Integer);
begin
  FAlter := Value;
end;

procedure TKontakt.SetName(const Value: String);
begin
  FName := Value;
end;

{ TCollection }

procedure TKontaktCollection.Add(Item: TKontakt);
begin
  FInnerList.Add(Item);
end;

function TKontaktCollection.Count: Integer;
begin
  Result := FInnerLIst.Count;
end;

constructor TKontaktCollection.Create;
begin
  inherited;
  FInnerList := TLIst.Create;
end;

destructor TKontaktCollection.Destroy;
var
  i                : Integer;
begin
  if FInnerList.Count > 0 then
  begin
    for i := FInnerList.Count - 1 to 0 do
    begin
      TObject(FInnerList.Items[i]).Free;
    end;
  end;
  inherited;
end;

function TKontaktCollection.GetItem(Index: Integer): TKontakt;
begin
  Result := FInnerList.Items[Index];
end;

procedure TKontaktCollection.SetItem(Index: Integer; const Value: TKontakt);
begin
  FInnerList.Items[Index] := Value;
end;

end.
Wie stelle ich jetzt eine Kopie von TKontaktCollection her mitsamt der inneren List? Das ist das Problem. Den bisherigen Code hab eich leider nicht ganz verstanden, weil es doch irgendwie immer etwas durcheinander ging.

(Im Anhang das gesamte Projekt.)

Noinini 30. Mai 2007 15:08

Re: Objekt kopieren
 
Hier die zwei notwendigen Methoden, allerdings ungetestet und ohne, dass ich mir das Projekt angesehen habe:

Delphi-Quellcode:
procedure TKontakt.Assign(Source: TKontakt);
begin
  Name := Source.Name;
  Alter := Source.Alter;
end;

procedure TKontaktCollection.Assign(source: TKontaktcollection);
var
  i: Integer;
  kontakt: TKontakt;
begin
  clear;
  for i := 0 to source.count-1 do
  begin
    kontakt := Add(TKontakt.Create);
    kontakt.Assign(source.Items[i]);
  end;
end;

Luckie 30. Mai 2007 15:29

Re: Objekt kopieren
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich glaube ich habs:
Delphi-Quellcode:
procedure TKontakt.Assign(Source: TKontakt);
begin
  Name := Source.Name;
  Alter := Source.Alter;
end;
Und:
Delphi-Quellcode:
procedure TKontaktCollection.Assign(Source: TKontaktCollection);
var
  i: Integer;
  kontakt: TKontakt;
begin
  for i := 0 to source.count-1 do
  begin
    kontakt := TKontakt.Create;
    kontakt.Assign(source.Items[i]);
    Add(kontakt);
  end;
end;
Der Test:
Delphi-Quellcode:
procedure TForm1.Button2Click(Sender: TObject);
var
  TempCollection: TKontaktCollection;
  i: Integer;
begin
  TempCollection := TKontaktCollection.Create;
  try
    TempCollection.Assign(Adressen);
    for i := 0 to TempCollection.Count - 1 do
    begin
      TempCollection.Items[i].Name := TempCollection.Items[i].Name + ' ist doof.';
      ListBox2.Items.Add(TempCollection.Items[i].Name);
    end;
  finally
    TempCollection.Free;
  end;
end;
und:
Delphi-Quellcode:
procedure TForm1.UpdateLB1;
var
  i: Integer;
begin
  Listbox1.Clear;
  for i := 0 to Adressen.Count - 1 do
    ListBox1.Items.Add(Adressen.Items[i].Name + ', ' + IntToStr(Adressen.Items[i].Alter));
end;
Die TempCollection wird am Ende der Procedure ja freigegeben. Wären jetzt nur Pointer in der Liste, würde Prozedur UpdateLB1 gar nichts mehr ausgeben - tut sie aber. Ergo wurden die Objekte kopiert und nicht nur die Pointer. Oder sehe ich das falsch?

Im Anhang das ganze Projekt.

shmia 30. Mai 2007 16:55

Re: Objekt kopieren
 
Zitat:

Zitat von Luckie
Ich glaube ich habs:
Delphi-Quellcode:
procedure TKontakt.Assign(Source: TKontakt);
begin
  Name := Source.Name;
  Alter := Source.Alter;
end;

Nicht ganz; schau nochmals in Beitrag #14.
Delphi-Quellcode:
procedure TKontakt.Assign(Source: TPersistent);
begin
  if Source is TKontakt then
  begin
    Name := TKontakt(Source).Name;
    Alter := TKontakt(Source).Alter;
  end
  // weitere (fiktive) Klasse, die zugewiesen werden könnte
  else if Source is TPerson then
  begin
    Name := TPerson(Source).FirstName + ' ' + TPerson(Source).LastName;
    Alter := round((now - TPerson(Source).BirthDate) / 365.0);
  end
  // Wichtig!! wenn mir die Source-Klasse nicht bekannt ist, inherited aufrufen
  else inherited;
end;

Luckie 30. Mai 2007 17:02

Re: Objekt kopieren
 
Jupp. Es fehlen zwei Zeilen (Source is TKontakt und inherited), das habe ich mir mal schnell gespart, da eh nichts anderes da ankommen kann. ;)

Aber ich habe das dumpfe Gefühl bei meiner TIMageEnVect-Komponente kopiert Assign nichts, so dass ich alles selber von Hand kopieren muss. :?

shmia 30. Mai 2007 17:12

Re: Objekt kopieren
 
Zitat:

Zitat von Luckie
... das habe ich mir mal schnell gespart...

Wenn man sich nicht an die Regeln hält, kann das später Dir (meist trifft's aber Andere) Probleme bereiten.
Denk an den *Supertrick* der VCL falls Assign nicht fruchtet die AssignTo-Methode aufzurufen.
Ohne das inherited kann der Trick nicht funktionieren.
Zitat:

Zitat von Luckie
Aber ich habe das dumpfe Gefühl bei meiner TIMageEnVect-Komponente kopiert Assign nichts, so dass ich alles selber von Hand kopieren muss. :?

Da hat sich der Author der TIMageEnVect-Komponente nicht an die Regeln gehalten!!

Luckie 30. Mai 2007 20:14

Re: Objekt kopieren
 
Zu mindest kommt zum Beispiel die Breite nur korrekt an, wenn ich sie explizit zuweise. :?


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:20 Uhr.

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