AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Erzeugen und Freigeben von Objekten und Speicher
Thema durchsuchen
Ansicht
Themen-Optionen

Erzeugen und Freigeben von Objekten und Speicher

Ein Thema von guidobrose · begonnen am 4. Jun 2007 · letzter Beitrag vom 5. Jun 2007
Antwort Antwort
guidobrose
(Gast)

n/a Beiträge
 
#1

Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 11:35
Ich hätte einmal eine grundsätzliche Frage zu Objekten.

Ich möchte die Objects Eigenschaft des StringGrid verwenden, um zusätzliche Formatierungsoptionen für die einzelne Zelle zu speichern. Ggf. soll über die neue Eigenschaft IsBitmap auch eine Grafik angezeigt werden können.

Hier einmal eine beispielhafte Deklaration des Objektes für die Eingenschaften:
Delphi-Quellcode:
type

  TCellOption = class(TObject)
  public
    Font: TFont;
    IsBitmap: Boolean;
    Bitmap: TBitmap;
  end;

  ...
Hier wäre jetzt die Zuweisung an jede Zelle des StringGrid:

Delphi-Quellcode:
  ACellOption:=TCellOption.Create;
  StringGrid.Objects[..]:=ACellOption;
Jetzt kann ich allerdings noch nichts an Font zuweisen, weil ja noch keine Instanz davon erzeugt wurde, also könnte es so aussehen:

Delphi-Quellcode:
  ACellOption:=TCellOption.Create;
  ACellOption.Font:=TFont.Create;
  ACellOption.Font.Assign(Font);
  StringGrid.Objects[..]:=ACellOption;
Genauso wird dann auch mit Bitmap verfahren nur zunächst ohne ein Bitmap zuzuweisen, da es ja nicht in jeder Zelle unbedingt benötigt wird.

Erste Frage:

Wenn ich die so erzeugten Objekte wieder freigeben möchte, welche Methoden muss ich dann aufrufen?

StringGrid.Objects[..].Free?

Damit ist die Instanz von TFont aber noch nicht freigegeben, oder?

Sollte ich also geschickterweise die create und destroy-Methoden von TCellOption überschreiben und darin die Instanz von TFont (und TBitmap) erzeugen und freigeben?

Zweite Frage:

Wie verhält es sich mit dem Speicherbedarf, wenn ich direkt eine Instanz von TBitmap pro Zelle erzeuge, ohne das ich sie evtl. wirklich benötige?

Danke und Gruß,
Guido
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#2

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 11:46
Hallo Guido,

du brauchst einen eigenen Destruktor, wenn das Objekt Eigentümer z.B. des Font sein soll. Anders wäre es, wenn nur eine Referenz gespeichert würde.

Was die Bitmap angeht: Probiere es einfach aus und messe den Verbrauch, dann weißt du wie skalierfähig dein Ansatz ist. Oft verwaltet man Bilder in einer ImageList und setzt beim Objekt nur eine Referenz, aber das musst du erkennen.

Grüße vom marabu
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#3

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 11:50
Zitat von guidobrose:
Erste Frage:
Wenn ich die so erzeugten Objekte wieder freigeben möchte, welche Methoden muss ich dann aufrufen?
StringGrid.Objects[..].Free?
Ja!
Zitat von guidobrose:
Damit ist die Instanz von TFont aber noch nicht freigegeben, oder?
Dafür ist die Klasse TCellOption verantwortlich.
Zitat von guidobrose:
Sollte ich also geschickterweise die create und destroy-Methoden von TCellOption überschreiben und darin die Instanz von TFont (und TBitmap) erzeugen und freigeben?
Definitiv!!

Zitat von guidobrose:
Zweite Frage:
Wie verhält es sich mit dem Speicherbedarf, wenn ich direkt eine Instanz von TBitmap pro Zelle erzeuge, ohne das ich sie evtl. wirklich benötige?
Der benötigte Platz eines leere Bitmap-Objekts lässt sich über die Funktion InstanceSize abfragen.
Eingebettete Objekte werden dabei nicht berücksichtigt (bzw. nur 4 Bytes für den Objektzeiger).
Ein gefülltes Bitmap benötigt dann noch zusätzliche Resourcen.
Andreas
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#4

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 11:59
Zitat von guidobrose:
Jetzt kann ich allerdings noch nichts an Font zuweisen, weil ja noch keine Instanz davon erzeugt wurde, also könnte es so aussehen:

Delphi-Quellcode:
  ACellOption:=TCellOption.Create;
  ACellOption.Font:=TFont.Create;
  ACellOption.Font.Assign(Font);
  StringGrid.Objects[..]:=ACellOption;
Genauso wird dann auch mit Bitmap verfahren nur zunächst ohne ein Bitmap zuzuweisen, da es ja nicht in jeder Zelle unbedingt benötigt wird.
Hi,
hier gibt es schon die erste Stelle an der Du aufpassen solltest. Wenn Du mit Create eine neue Instanz erzeugst, dann wird Dir eine Referenz auf dieses neue Objekt zurück gegeben. Genau diese Referenz wird in ACellOption.Font gespeichert. Weißt Du hier einer TCellOption zweimal einen Font zu, so überschreibst Du nur die alte Referenz. Das Objekt, dass Du angelegt hast würde einfach im Speicher bleiben (und wäre nicht mehr erreichbar). Besser ist es hier, dass Du vorher ein Free aufrufst um sicherzustellen, dass es keine erste Instanz gibst, die sonst ein Speicherleck darstellt.

Zitat von guidobrose:
Erste Frage:

Wenn ich die so erzeugten Objekte wieder freigeben möchte, welche Methoden muss ich dann aufrufen?

StringGrid.Objects[..].Free?

Damit ist die Instanz von TFont aber noch nicht freigegeben, oder?
Korrekt!

Zitat von guidobrose:
Sollte ich also geschickterweise die create und destroy-Methoden von TCellOption überschreiben und darin die Instanz von TFont (und TBitmap) erzeugen und freigeben?
Ja!

Zitat von guidobrose:
Zweite Frage:

Wie verhält es sich mit dem Speicherbedarf, wenn ich direkt eine Instanz von TBitmap pro Zelle erzeuge, ohne das ich sie evtl. wirklich benötige?
Du hast einen recht geringen Speicherbedarf. Das was ein Bitmap-Objekt wirklich groß macht ist die eigentliche Bitmap (das Bild). Ein TBitmap-Objekt besteht aus ein wenig mehr, so hast Du halt die Meta-Informationen einer Bitmap (Höhe, Breite, Farbtiefe, ...) und ein wenig VCL-Overhead (Handle, Pen, Brush, Canvas,...) aber an sich sollten dass nur ein paar zig oder hundert Byte sein. Das eigentlich große kommt erst hinzu, wenn Du hier eine TBitmap zuweist.

An sich wäre eventuell eine gute Möglichkeit für Dich, dass Du die Zuweisung über Properties vornimmst. Die erlauben es Dir, dass Du eben Speicher nur bei Bedarf zuweist.
Grob könnte es die folgende Form haben:
Delphi-Quellcode:
TCellOption = class(TObject)
  private
    FFont: TFont;
    Bitmap: TBitmap;
  protected
    procedure setBitmap(const Bitmap: TBitmap);
    procedure setFont(const Font: TFont);
  public
    destructor Destroy; override;
    function hasBitmap(): Boolean;
    
    property Bitmap: TBitmap read FBitmap write setBitmap;
    property Font: TFont read FFont write setFont;
  end;
Die Implementierung könnte dann so aussehen:
Delphi-Quellcode:
destructor TCellOption.Destroy;
begin
  self.FBitmap.Free;
  self.FFont.Free;
 
  inherited Destroy;
end;

function TCellOption.hasBitmap: Boolean;
begin
  result := assgigned(self.FBitmap);
end;

procedure TCellOption.setBitmap(const Bitmap: TBitmap);
begin
  if assigned(Bitmap) then
  begin
    // wenn self.FBitmap nichts zugewiesen ist
    // wird einen neue Instanz erzeugt
    if not assigned(self.FBitmap) then
    begin
      self.FBitmap := TBitmap.Create;
    end;

    self.FBitmap.Assign(Bitmap);
  end

  // wenn dem TBitmap-Objekt nil zugewiesen wird, dann wird die Bitmap einfach gelöscht
  else
  begin
    self.FBitmap.Free;
    self.FBitmap := nil;
  end;
end;

// analog für setFont
Gruß Der Unwissende

[roter Kasten]
Ok, das meiste hier wurde schon gesagt, aber ich poste es mal trotzdem!
[/roter Kasten]
  Mit Zitat antworten Zitat
guidobrose
(Gast)

n/a Beiträge
 
#5

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 12:17
Danke für die Antworten! Ich bin ja anscheinend auf dem richtigen Weg und werde die hier erhaltenen Informationen mal in ein paar Versuchen verwerten.

Kurze Nachfrage noch:

Was bewirken denn self.FBitmap oder self.FFont.Free ?

Wo liegt der Unterschied zu FFont.Free?

Danke.
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#6

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 12:20
Zitat von guidobrose:
Kurze Nachfrage noch:

Was bewirken denn self.FBitmap oder self.FFont.Free ?

Wo liegt der Unterschied zu FFont.Free?
Es gibt keinen direkten Unterschied! Mit self qualifiziert man nur Instanzvariablen. Das heißt, dass self zeigt nur deutlicher an, dass es sich eben um Variablen handelt, die zur gleichen Instanz gehören, zu denen auch der Methodenaufruf gehört. Hättest Du zum Beispiel Instanzvariablen, die den gleichen Namen haben, wie eine lokale Variable, kannst Du die so unterscheiden
  Mit Zitat antworten Zitat
Benutzerbild von Jelly
Jelly

Registriert seit: 11. Apr 2003
Ort: Moestroff (Luxemburg)
3.741 Beiträge
 
Delphi 2007 Professional
 
#7

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 4. Jun 2007, 12:53
Ich würde bereits im constructor von TCellOption eine Instanz von Font und Bitmap erstellen, und diese im Destructor natürlich auch wieder freigeben.

So kann von aussen, nach Erstellen einer TCellOption Instanz direkt auf dessen Font und Bitmap zugegriffen werden, ohne eine Zugriffsverletzung zu bekommen.
  Mit Zitat antworten Zitat
guidobrose
(Gast)

n/a Beiträge
 
#8

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 5. Jun 2007, 13:22
Da es gut zum Thema passt, noch eine Frage hinterher:

Wenn ich eine Instanz mit Create(AOwner) erzeuge muss ich dies dann wieder explizit Freigeben oder erlegigt das der Owner automatisch, wenn er freigegeben wird?

z.B. Erstelle ich auf einem Formular eine x-beliebige Komponente:

Delphi-Quellcode:
procedure TForm1.Create;
begin
  Panel:=TPanel.Create(self);
  Panel.Parent:=Form1;
end;
Ist dann in TForm1.Destroy noch notwendig Panel.Free aufzurufen?
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.276 Beiträge
 
Delphi 10.4 Sydney
 
#9

Re: Erzeugen und Freigeben von Objekten und Speicher

  Alt 5. Jun 2007, 13:32
Hallo,

durch das .(Self) wird das Form der Owner
und gibt das Panel auch frei.

Ich empfehle memcheck, um Speicherfehler zu finden.


Heiko
Heiko
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 13:32 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