Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Object in Variable sichern? (https://www.delphipraxis.net/75304-object-variable-sichern.html)

moelski 17. Aug 2006 13:30


Object in Variable sichern?
 
Moin !

Ich stehe da mal wieder vor einem kleinen Object bzw. Klassen Problem :roll:

Also wir haben da ein paar Klassen für Geräte. die nennen sich dann z.B.
TLVSpectraII und TLVPowerPeak.

Je nachdem welches Gerät wir nun gerade bedienen müssen wir ein Object von der Klasse erzeugen.
Bis hierhin noch einfach ...
SpectraII := TLVSpectraII.Create(Self);

Nun würde ich aber gerne irgendwie das zuletzt erzeugte Object sichern. Weil wenn ich ein anderes Gerät lade, dann möchte ich in dieser Variable nachsehen welches Object aktuell ist und dieses dann löschen. Danach kann dann das neue Object angelegt werden.

Ich hatte es hiermit versucht:
LastObject := SpectraII;

Wobei folgendes definiert ist: LastObject : TObject;

Aber so scheint es nicht wirklich zu funktionieren. Denn ein LastObject.Destroy bewirkt gonix.


Kann mir da jemand einen Tip geben?

Greetz Dominik

rwachtel 17. Aug 2006 13:37

Re: Object in Variable sichern?
 
Ja, verwende niemals, nie Destroy direkt, sondern Free.

shmia 17. Aug 2006 13:37

Re: Object in Variable sichern?
 
Zitat:

Zitat von moelski
Wobei folgendes definiert ist: LastObject : TObject;

Deine Klassen sind von TComponent abgeleitet ?
Delphi-Quellcode:
var
LastObject : TComponent; // besser man nimmt den gemeinsamen Vorfahren aals Datentyp
Oder sind es visuelle Komponenten (=Steuerelemente)?
Dann wäre TControl die passende Klasse.

moelski 17. Aug 2006 13:40

Re: Object in Variable sichern?
 
Moin !

Zitat:

Ja, verwende niemals, nie Destroy direkt, sondern Free.
Ok, aber das ist ja noch keine Antwort auf meine Frage :-D

Zitat:

Deine Klassen sind von TComponent abgeleitet ?
Ja erstmal ist das so: TLVSpectraII = class(TObject)

Zitat:

Oder sind es visuelle Komponenten (=Steuerelemente)?
Nein sind keine visuelen Komponenten.

shmia 17. Aug 2006 13:49

Re: Object in Variable sichern?
 
Zitat:

Zitat von moelski
Ja erstmal ist das so: TLVSpectraII = class(TObject)

Ich würde empfehlen:
1.) von TPersistent statt TObject abzuleiten (die Vorteile merkst du aber erst mit zunehmender Erfahrung)
2.) eine gemeinsame Basisklasse für alle Geräte schaffen
Delphi-Quellcode:
TLVDevice = class(TPersistent)
end;
TLVSpectraII = class(TLVDevice)
3.) überlegen, welche Eigenschaften um Methoden allen Klassen gemeinsam sind
um diese in die Basisklasse zu verlagern
z.B. könnte jedes Gerät einen Gerätenamen haben (property DeviceName)
oder jedes Gerät muss geöffnet und geschlossen werden
Delphi-Quellcode:
procedure Open; virtual;
procedure Close; virtual;

rwachtel 17. Aug 2006 13:55

Re: Object in Variable sichern?
 
Zitat:

Zitat von moelski
[...] LastObject := SpectraII;

Wobei folgendes definiert ist: LastObject : TObject;

Aber so scheint es nicht wirklich zu funktionieren. Denn ein LastObject.Destroy bewirkt gonix.[...]

Wie hast Du das festgestellt? Folgendes funktioniert:

Delphi-Quellcode:
  TKlasseA = class(TObject)
  public
    destructor Destroy; override;
  end;

  TKlasseB = class(TObject)
  public
    destructor Destroy; override;
  end;

implementation

destructor TKlasseA.Destroy;
begin
  ShowMessage('Klasse A sagt Bye-bye...');
  inherited;
end;

destructor TKlasseB.Destroy;
begin
  ShowMessage('Klasse B sagt Bye-bye...');
  inherited;
end;

[...]
var
  KlasseA: TKlasseA;
  Klasse: TObject;
begin
  KlasseA := TKlasseA.Create;
  Klasse := KlasseA;
  Klasse.Free;
end;

moelski 17. Aug 2006 14:00

Re: Object in Variable sichern?
 
Moin !

@shmia:
Danke für den Tip. Das kann man machen. So in etwa wäre es bei uns der nächste Schritt gewesen. Aber das kann man ja auch vorziehen.

Zitat:

überlegen, welche Eigenschaften um Methoden allen Klassen gemeinsam sind
Eigentlich haben die garnix gemein. Jede Klasse hat ihre speziellen Funktionen. Gemein ist nur Create, Free, etc ... Aber das ist ja soweiso durch die Vererbung in der Klasse vorhanden.

Die Sache mit Open und Close würde sicher funktionieren. Ist aber mit Mehraufwand verbunden, der irgendwann überflüssig wird. Wir wollen irgendwann mehrere Geräte parallel bedienen. Dazu muss ich mir dann eh irgendwo merken welche Objekte existieren.

Also mein Grundproblem besteht nach wie vor. Wie kann ich ein Object in einer Varible sichern? Ich denke das geht mit einem Zeiger. Weiss aber nicht wie ...

@rwachtel:
Zitat:

Wie hast Du das festgestellt?
Nuja, ich habe folgendes probiert:
Delphi-Quellcode:
  SpectraII := TLVSpectraII.Create(Self);
  LastObject := SpectraII;
  LastObject.free;
Danach habe ich eine Datei geladen die das Objekt SpectraII verwendet. Aber da ich keine Exception bekommen habe muss es immer noch existent gewesen sein.

Muetze1 17. Aug 2006 14:02

Re: Object in Variable sichern?
 
Zitat:

Zitat von moelski
Danach habe ich eine Datei geladen die das Objekt SpectraII verwendet. Aber da ich keine Exception bekommen habe muss es immer noch existent gewesen sein.

Nein, das bedeutet nur, das der Speicherbereich noch nicht erneut verwendet wird bzw. der Inhalt sich noch nicht geändert hat und du somit pures Glück hattest, das es zu keinem Absturz kam.

moelski 17. Aug 2006 14:04

Re: Object in Variable sichern?
 
Aha, also funktioniert das so wie ich es gemacht habe?

Also erst ...
Delphi-Quellcode:
var
  LastObject: TObject;
und dann halt
Delphi-Quellcode:
  SpectraII := TLVSpectraII.Create(Self);
  LastObject := SpectraII;
Wenn ich dann ein neues Gerät bedienen will tue ich folgendes:

Delphi-Quellcode:
LastObject.free;
neuesGeraet := TLVneuesGeraet.Create(Self);
LastObject := neuesGeraet;

rwachtel 17. Aug 2006 14:05

Re: Object in Variable sichern?
 
Zitat:

Zitat von moelski
[...] ich habe folgendes probiert:
Delphi-Quellcode:
  SpectraII := TLVSpectraII.Create(Self);
  LastObject := SpectraII;
  LastObject.free;
Danach habe ich eine Datei geladen die das Objekt SpectraII verwendet. Aber da ich keine Exception bekommen habe muss es immer noch existent gewesen sein.

Ups, wahrscheinlich war einfach der Speicherbereich zufällig noch nicht überschrieben. Folgendes "funktioniert" auch:

Delphi-Quellcode:
  TKlasseA = class(TObject)
  public
    destructor Destroy; override;
    procedure WhoAmI;
  end;

implementation

destructor TKlasseA.Destroy;
begin
  ShowMessage('Klasse A sagt Bye-bye...');
  inherited;
end;

procedure TKlasseA.WhoAmI;
begin
  ShowMessage('Ich bin Klasse A.');
end;

[...]

var
  KlasseA: TKlasseA;
  Klasse: TObject;
begin
  KlasseA := TKlasseA.Create;
  Klasse := KlasseA;
  Klasse.Free;
  KlasseA.WhoAmI;
end;

rwachtel 17. Aug 2006 14:06

Re: Object in Variable sichern?
 
Zitat:

Zitat von moelski
Aha, also funktioniert das so wie ich es gemacht habe? [...]

Ja.

moelski 17. Aug 2006 14:07

Re: Object in Variable sichern?
 
Ok, dann bin ich erstmal glucklitsch :-D

Vielen Dank für die Antworten !! :hello:

moelski 17. Aug 2006 14:11

Re: Object in Variable sichern?
 
Moin nochmal ...

Öhm so ganz scheint das aber noch nicht zu gehen.

Wenn ich folgendes schreibe:
Delphi-Quellcode:
LastObject := SpectraII;
Dann müsste ich doch mittels LastObject auf Funktionen von SpectraII zugreifen können oder nicht?
Weil das bräuchte ich auch ...

Das funktioniert aber so nicht, denn ich bekomme den Fehler "[Fehler] DeviceUtils.pas(1023): Undefinierter Bezeichner: 'IsLogData'"
Der Aufruf war:
Delphi-Quellcode:
LastObject.IsLogData(Data);
Wie kriege ich das denn hin das LastObject.IsLogData funktioniert?

rwachtel 17. Aug 2006 14:17

Re: Object in Variable sichern?
 
Nein, Du kannst nur auf die Methoden und Eigenschaften der Basisklasse (hier: TObject) zugreifen.

Abhilfe schafft ein Typecasting:
Delphi-Quellcode:
TSpectraII(LastObject).IsLog(Data);
Daher der Tipp mit der Basisklasse und den virtuellen Methoden.

moelski 17. Aug 2006 14:17

Re: Object in Variable sichern?
 
Ah ok. Das hilft mir weiter.

Vielen Dank !

DGL-luke 17. Aug 2006 14:23

Re: Object in Variable sichern?
 
LastObject ist als TObject deklariert. Der Compiler kann also nicht wissen, dass deine eigene Klasse dahintersteckt. Du musst also entweder einen Typecast machen:

Delphi-Quellcode:
TSpectraII(LastObject).IsLog(Data); //hart
(LastObject as TSpectraII).IsLog(Data); //weich
ein weicher cast ist übrigens meist vorzuziehen, dabei wird eine überprüfung vorgenommen, ob auch wirklich das richtige objekt vorliegt.

ansonsten solltest du eine basisklasse definieren, die diese methode bereits enthält, wie rwachtel geschrieben hat. das geht so:

Delphi-Quellcode:
type
  TDevice = class {abstract} (TObject); //class abstract funktioniert ab Delphi 2005
  public
    function IsLogData: Boolean; virtual; abstract;
  end;
das schlüsselwort "virtual" besagt, dass die methode in einer nachfolgerklasse überschrieben werden kann, "abstract", dass sie in dieser Klasse nicht implementiert (=ausprogrammiert) wird.

überschrieben wird sie dann so:

Delphi-Quellcode:
type
  TSpectraII = class(TDevice)
  public
    function IsLogData; override;
  end;
override sorgt dafpr, dass der aufruf von IsLogData nicht auf die abstrakte Methode des vorgängers prallt, sondern auf die tatsächliche klasse umgeleitet wird.

Muetze1 17. Aug 2006 21:18

Re: Object in Variable sichern?
 
Zitat:

Zitat von rwachtel
Abhilfe schafft ein Typecasting:
Delphi-Quellcode:
TSpectraII(LastObject).IsLog(Data);

Er hat mehrere unterschiedliche Klassen in LastObject - das ist in so fern richtig gefährlich einen harten Typecast zu empfehlen - das ist mehr als gefährlich sowas als Antwort zu posten! Harter Typecast wäre ok, wenn vorher der Klassentyp mit dem IS Operator überprüft wurde. Oder halt ein weicher Typecast, dieser liefert NIL, wenn die Klasse nicht stimmt - da er selber nochmal einen Vergleich mit IS vornimmt.

Khabarakh 17. Aug 2006 21:57

Re: Object in Variable sichern?
 
Zitat:

Zitat von Muetze1
Oder halt ein weicher Typecast, dieser liefert NIL, wenn die Klasse nicht stimmt - da er selber nochmal einen Vergleich mit IS vornimmt.

So funktioniert der Operator in anderen Sprachen, under Anderem C#, in Delphi jedoch wird eine EInvalidCast-Exception geworfen.

Muetze1 17. Aug 2006 23:22

Re: Object in Variable sichern?
 
Zitat:

Zitat von Khabarakh
Zitat:

Zitat von Muetze1
Oder halt ein weicher Typecast, dieser liefert NIL, wenn die Klasse nicht stimmt - da er selber nochmal einen Vergleich mit IS vornimmt.

So funktioniert der Operator in anderen Sprachen, under Anderem C#, in Delphi jedoch wird eine EInvalidCast-Exception geworfen.

Sorry, stimmt, mein Fehler. So manchmal kommt man doch schon durcheinander...


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