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 Referenzen auf Objekte, die free werden (https://www.delphipraxis.net/95153-referenzen-auf-objekte-die-free-werden.html)

drchaos 2. Jul 2007 01:37


Referenzen auf Objekte, die free werden
 
Hallo!

Folgende Situation: Ich habe zwei Klassen, eine von beiden hält eine Referenz auf ein Objekt der anderen Klasse.
Zum Beispiel so:

Delphi-Quellcode:
  TIchWerdeBenutzt = class
    constructor Create; overload;
    destructor Destroy; override;
  private
    data: String;
  end;


  TIchBenutze = class
    constructor Create; overload;
    constructor Create(IchWerdeBenutzt: TIchWerdeBenutzt); overload;
    destructor Destroy; override;
  private
    denBenutzeIch: TIchWerdeBenutzt ;
  end;
Angenommen, irgendwo wird mit freeandnil das Objekt, auf das "denBenutzeIch" zeigt, freigegeben; jedoch wird freeandnil NICHT auf "TIchBenutze.denBenutzeIch" angewandt, sondern auf die ursprünglich erzeugte (z.B. globale) Objektvariable.
Dann zeigt das Feld "denBenutzeIch" zwar nicht mehr auf ein gültiges Objekt, ist aber auch nicht nil. (es sollte klar sein, warum?)

Ich möchte aber, dass "denBenutzeIch" auch nil wird. Wie kann ich das erreichen?

Ich denke nun darüber nach, in der Klasse "TIchWerdeBenutzt" eine Liste von allen anderen Objekten zu speichern, die Referenzen darauf halten, um diese informieren zu können, wenn das "TIchWerdeBenutzt" - Objekt freigegeben wird.

Gibt es vielleicht noch eine andere (elegantere, einfachere) Möglichkeit?

cruiser 2. Jul 2007 03:46

Re: Referenzen auf Objekte, die free werden
 
Erklär mal, was genau du machen willst. Evtl. findet sich dann ein Weg, der an einer Listenhaltung vorbei führt.

Hab bisschen Rumgetüftelt. Du kannst zwar nicht auf nil prüfen, aber du kannst den ClassType deiner Referenz gegen den soll-Classtype prüfen:

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

uses Windows, SysUtils, Classes;

{ TCl1 }

type TCl1 = class(TObject)
private
  fs: AnsiString;
public
  constructor Create(const s:AnsiString); reintroduce;
end;

constructor TCl1.Create(const s: AnsiString);
begin
  fs := s;
end;

{ TCl2 }

type TCl2 = class(TObject)
private
  fo: TCl1;
public
  constructor Create(o:TCl1); reintroduce;
  function Check: Boolean;
end;

function TCl2.Check: Boolean;
begin
  Result := (fo.ClassType = TCl1);
end;

constructor TCl2.Create(o: TCl1);
begin
  fo := o;
end;

var
  o1: TCl1;
  o2: TCl2;
begin
  try
    o1 := TCl1.Create('Test');
    o2 := TCl2.Create(o1);

    FreeAndNil(o1);

    if o2.Check then
      Writeln('Referenziertes Objekt (o1) existiert noch') else
      Writeln('Referenziertes Objekt (o1) wurde frei gegeben');

  finally
    FreeAndNil(o2);
    Sleep(5000);
  end;
end.

alzaimar 2. Jul 2007 08:16

Re: Referenzen auf Objekte, die free werden
 
Das halte ich für nicht praktikabel (weil unsauber). Ich würde eher der Klasse 'TIchwertebenutzt' ein Event 'OnDestroy' spendieren, über das benutzende Instanzen die Referenz ggf löschen können.

dataspider 2. Jul 2007 08:19

Re: Referenzen auf Objekte, die free werden
 
Hi Ronny,

bei allen von TComponent abgeleiteten Klassen ist es einfach.
Da ruftst du FreeNotification auf und überschreibst die Methode Notification.
Wenn du von TObject ableitest, musst du das selbst managen.
Aber hier finde ich deinen Ansatz mit der Liste schon richtig.

Cu, Frank

alzaimar 2. Jul 2007 08:57

Re: Referenzen auf Objekte, die free werden
 
Das mit der Liste (und dem Handle) hatte ich überlesen: Ich empfinde das auch als sauber

cruiser 2. Jul 2007 10:01

Re: Referenzen auf Objekte, die free werden
 
Besonders sauber finde ich das auch nicht mit dem ClassType prüfen. Geb ich offen zu.

Eine Liste (ob nun verkettet oder durch TList implementiert) oder Collection wär eine Möglichkeit. Die einzige, die auch sauber ist. Wenn DrChaos uns aber verrät in welchem größeren Zusammenhang das steht, könnt er das aber evtl. auch noch anders umgehen. Aus den Beiden Klassen heraus wüsste ich jedenfalls auch nichts andres als Listenhaltung. Ein einzelnes Event OnDestroy ist jedenfalls auch nich so praktisch. Denn dann kann immer nur eine Klasse, die das Objekt mit dem String hält sich eintragen (oder seh ich das falsch?).

drchaos 2. Jul 2007 10:21

Re: Referenzen auf Objekte, die free werden
 
Zitat:

Zitat von cruiser
Erklär mal, was genau du machen willst. Evtl. findet sich dann ein Weg, der an einer Listenhaltung vorbei führt.

Das Beispiel war natürlich nur so gewählt, dass es überschaubar bleibt. Eigentlich bin ich gerade dabei, eine kleine Simulation für ein Peer-to-Peer - Netzwerk zu schreiben... Peers werden in einer Klasse TPeer repräsentiert. Jeder Peer wiederum kennt in seiner Routingliste eine Menge anderer Peers. Zwar könnte ich in der Liste auch nur die IP-Adressen (welche durch eine eindeutige Integerzahl repräsentiert werden) speichern, aber dann müsste ein Peer erstmal eine Suche nach dem Objekt zu einer bestimmten Adresse durchführen, bevor er dieses ansprechen könnte.

Da die Simulation recht viele Peers beinhalten soll (10Tausend bis 10Mio... je mehr, desto besser ;) ), ist eine Suche über die IP nicht praktikabel (zu langsam, selbst wenn man das in O(log(n)) macht).

Deshalb bekommt nun jeder Peer eine OutgoingLink-Liste spendiert, in der er über Objektreferenzen direkt seine Nachbarn ansprechen kann. Da auch der Wegfall von Peers simuliert werden soll (entweder klinken sie sich ordentlich vom Netz aus, oder ihr Computer stürzt ab so dass sie sich nicht mehr abmelden können), muss ein TPeer-Objekt wissen, wann seine Links auf andere TPeer ungültig geworden sind.

Ich werde das nun durch eine IncomingLink-Liste machen, so dass jeder Peer auch umgekehrt wissen kann, wer einen Link auf ihn hält. So kann er sich bei ihnen abmelden und es hat den Vorteil, dass ich so auch erfahren kann, wie viele andere Computer einen bestimmten Peer jeweils als Routingpartner ausgewählt haben. Zuviele sollten das nämlich auch nicht werden, die Last sollte sich gleichmäßig auf alle verteilen... anhand der Zahl der Listeneinträge kann ich das dann sogar direkt messen.

Vielen Dank erstmal für die Ratschläge, das hat mir geholfen... wirklich ein nettes Forum hier :-D

Gruß,
Helge

alzaimar 2. Jul 2007 10:30

Re: Referenzen auf Objekte, die free werden
 
Zitat:

Zitat von drchaos
[... ist eine Suche über die IP nicht praktikabel (zu langsam, selbst wenn man das in O(log(n)) macht).

Suchen kann man auch in O(1), nämlich in einem Trie oder einer Hashmap. Ein Trie ist etwas schneller, verbrät aber wesentlich mehr Speicher.

drchaos 2. Jul 2007 11:04

Re: Referenzen auf Objekte, die free werden
 
Trie (Prefix-Trees) kannte ich gar nicht, habe ich gerade in der Wikipedia nachgelesen... leider wäre der Baum bei mir irgendwann komplett gefüllt, dann habe ich log(n). Aber hashmaps wären vielleicht eine gute Möglichkeit... in der JCL (JEDI Code Library, http://www.delphi-jedi.org/) scheint es Hashmap-Implementierungen zu geben, sind die gut? (wahrscheinlich blöde Frage. aber ich habe ewig nichts richtiges mehr mit delphi programmiert und kenne die apis nicht mehr)

alzaimar 2. Jul 2007 11:41

Re: Referenzen auf Objekte, die free werden
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von drchaos
Trie (Prefix-Trees) kannte ich gar nicht, habe ich gerade in der Wikipedia nachgelesen... leider wäre der Baum bei mir irgendwann komplett gefüllt, dann habe ich log(n).

Ach, shi*** ich meinte DAWG. Ich werd' alt... Na egal. Also, ein DAWG oder eine Hashmap sollten reichen. Hagen Redmann hat mal eine DAWG-Klasse geschrieben, und die Hashmaps von Jedi.. kenn ich nicht, ich hab mir meine eigene gebastelt.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:26 Uhr.
Seite 1 von 2  1 2      

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