Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Create Destroy Problem (https://www.delphipraxis.net/81350-create-destroy-problem.html)

mrfunnywurstman 25. Nov 2006 16:19


Create Destroy Problem
 
Tach Leute!

Da ich im fach Informatik eine Lernleistung über die Implementierung dynamischer Grafiken unter Delphi anfertige habe ich nun folgendes Problem:

Wie kann ich es realisieren ein Shape zu erstellen, mit dem create befehl, bzw. zu zerstören mit dem destroy befehl? ICh habe die Such funktion hier im Forum schon genutzt und google auch, es kann natürlich sein das ich irgendwas übersehen habe. Das Programm soll eine Art Spiel werden, erstmal zu TEstzwecken, ich klicke auf etwas und dann wir das Shape created bewegt sich, und wenn es wo drauf trifft oder an den rand kommt wieder destroyt wird.

Danke im voraus.

mfg
-JEns :P

DGL-luke 25. Nov 2006 16:34

Re: Create Destroy Problem
 
Delphi-Quellcode:
var shapes: array of TShape; //so hast du deine Shapes immer schön an der Hand

setlength(shapes,1);

shapes[0] := TShape.Create(self);
shapes[0].Parent := self; //wichtig!
shapes[0].Left := ....;

mrfunnywurstman 25. Nov 2006 16:52

Re: Create Destroy Problem
 
ok, danke erstmal. nun muss ich aber noch wissen wie ich die dann wieder destroyen kann, mit einem anderen button zum beispiel, weil wenn ich

Delphi-Quellcode:
shapes[0].Destroy;
eintippe, dann krieg ich immer nen Access Violation Error.

Und bei:

Delphi-Quellcode:
shapes[0].Free;
passiert nichts.

mfg
-jens

Der_Unwissende 25. Nov 2006 17:16

Re: Create Destroy Problem
 
Hi und herzlich Willkommen in der DP :dp:

Zu dem Thema create/destroy gibt es gleich ein paar Dinge zu sagen. Am schönsten ist es natürlich, wenn du hier den Leuten hilfst, die dir helfen sollen und genauer sagst, was dir schon bekannt ist und was eben noch nicht. In diesem Fall wären Begriffe wie Konstruktor/Destruktor dass, wonach du schauen solltest.

Bei create handelt es sich um den Constructor, dieser wird benötigt um eine neue Instanz einer Klasse zu erzeugen. Die Klasse TObject besitzt einen speziellen Konstruktor, also sein Implmentierung ist speziell, denn hier wird tatsächlich ein neues Objekt erstellt, der Speicher reserviert usw. Jede andere Klasse ist immer ein Nachfahre von TObject und erbt deswegen diesen Konstruktor. Schreibst du einen eigenen ist deswegen der wichtigste Aufruf (der in deiner eigenen Implementierung als erstes erfolgen muss) inherited create (du rufst damit den geerbten Konstruktor auf, was irgendwann zum Aufruf des TObject.Create führt).

Rufst du einen Konstruktor auf, so wird eine Referenz auf das erzeugte Objekt zurückgegeben. Eine solche Referenz ist etwas wie ein Zeiger auf ein Objekt. Der Aufruf des Destruktors kann auf zwei Arten erfolgen, du kannst direkt den Destruktor aufrufen (Destroy) oder du verwendest die Methode Free. Diese prüft einfach nur, ob die Referenz <> nil ist und ruft ggf. den Destruktor auf.
Objekte die von TComponent erben besitzen einen Parent. Hier kann eine andere TComponent Instanz als Parent übergeben werden. Sollte der Parent zerstört werden, so werden auch alle Kinder zerstört. Weißt du also einer TComponent einen gültigen Parent zu, so brauchst (darfst) du dich nicht mehr um dessen freigabe kümmern, dies übernimmt der Parent für dich.

Bevor du die Instanz einer Klasse freigbist, solltest du immer darauf achten, dass diese nirgendwo mehr in Benutzung ist. Hier kommt wiederum der Fakt zu tragen, dass du hier mit Referenzen arbeitest. Diese Referenzen enthalten nur die zugewiesene Adresse, ist diese ungleich nil, gibt es für dich keine Möglichkeit festzustellen, ob dies eine gültige Referenz ist oder nicht.
Als kurzes Beispiel:
Delphi-Quellcode:
procedure doFoo;
var obj : TObject;
begin
  // An dieser Stelle ist der Wert von obj zufällig
  // Du kannst hier versuchen auf Eigenschaften von Obj zuzugreifen
  // Dabei liest/schreibst du einen zufälligen Speicherbereich, die Folgen
  // sind nicht absehbar
  // Ist die Adresse zufällig nil, so gibt es eine Access Violation (der Beste Fall!)

  // anlegen eines neuen Objekts
  obj := TObject.Create;
 
  // nun ist in obj eine gültige Referenz gespeichert
  obj.Free;
 
  // Die Instanz die obj referenziert hat wurde frei gegeben
  // die Adresse bleibt aber weiterhin gespeichert
  // und ist damit gültig
  // wieder würden Zugriffe zu Fehlern führen!
  obj.Free; // löst einen Fehler aus!

  obj := nil;
  obj.Free; // ohne Probleme mögllch
  obj.Destroy; // löst einen Fehler aus!   
end;
Dabei kannst du beliebig viele Referenzen auf ein und das selbe Objekt zeigen lassen. Hast du ein grafisches Element, z.B. ein Shape und fügst dies irgendwo ein, wo es angezeigt wird, so speichert diese andere Komponente (die das Shape anzeigt) nur die Referenz auf das Shape. Gibst du nun das Shape frei, wird die Referenz auch weiterhin als gültig betrachtet (da die Adresse ungleich nil ist). Dies führt dann (früher oder später) zu einem Fehler bei der Anzeige. Deshalb musst du die Referenz überall dort, wo du sie einträgst vorher wieder entfernen. Fügst du also ein Shape irgendwo zur Anzeige ein, muss es vor seiner Freigabe dort wieder entfernt werden und darf erst danach frei gegeben werden.

Gruß Der Unwissende


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:52 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 by Thomas Breitkreuz