Ohne Nil prüfen ob Objekt erstellt wurde.

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Gibt es eigentlich (neuerdings) eine Möglichkeit, so etwas wie "if Assigned()" zu machen, ohne dass man die Objektvariable vorher auf Nil setzt und ohne ein SIGSEGV abzufangen?
Bei Records kann man ja leider nicht von Nil, 0 etc ausgehen.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Michl »

Soviel ich weiß, werden nur globale Instanzen mit Nil vorbelegt.

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Michl hat geschrieben:Soviel ich weiß, werden nur globale Instanzen mit Nil vorbelegt.

Ja, das ist klar. Wie prüfe ich also in diesem Falle, ob ein Objekt schon erstellt ist?

Warf
Beiträge: 1910
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Warf »

Gar nicht, nicht mal eine seg fault ist garantiert, wenn später etwas anderes im Speicher steht kann an dieser Stelle auf die die Variable zeigt kann Gott weiß was passieren (z.b. ein zweites Objekt der selben klasse wird an der Stelle initialisiert, dann ist der Zeiger valide, obwohl du das so nie wolltest).

Die Zeiger musst du eben selbst mit Nil initialisieren

Ein Beispiel:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var sl, sl2: TStringList;
begin
  sl:=TStringList.Create;
  sl.Text:='A';
  sl.Free;
  sl2:=TStringList.Create;
  sl2.Text:='B';
  ShowMessage(sl.Text);
end;     


Resultat ist B, da der selbe Speicherbereich wieder verwendet wurde

Über einen Zeiger der nicht auf Nil steht kann man keine Aussage treffen

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Warf hat geschrieben:Die Zeiger musst du eben selbst mit Nil initialisieren


Das geht aber nicht. In einem (Advanced) Record habe ich afaik kein Create oder sowas.
Ich muss das Objekt erstellen, in dem Moment wo es angefordert wird und da habe ich also keine Chance zu erkennen, ob es schon da ist, außer über eine abgefangene Exception, was hässlich wäre.

Warf
Beiträge: 1910
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Warf »

Du könntest deine Records in einer separaten Datei mit Mode Delphi auslagern, dann dürfte es möglich sein konstruktoren zu verwenden

Und das mit der exception ist auch nicht sicher, siehe Beispiel oben

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Warf hat geschrieben:Du könntest deine Records in einer separaten Datei mit Mode Delphi auslagern, dann dürfte es möglich sein konstruktoren zu verwenden

Was meinst du damit?

Warf
Beiträge: 1910
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Warf »

Eine Separate Unit für die Record definition, bei dieser Unit setzt du den Compilerswitch {$MODE Delphi} und kannst dort dann einen Konstruktor für den Record schreiben

Code: Alles auswählen

unit TestRecord;
{$MODE Delphi}
interface
type
  TTestRec = record
    ...
    constructor Create;
  end;
 
implementation
 
constructor TTestRec.Create;
begin
  ...
end;
 
end.


Dann zum benutzen einfach diese Unit einbinden, und du hast einen Record mit Konstruktor so wie in Delphi

PS: habe ich nicht getestet, ist nur eine Vermutung dass es so geht

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Ich habe das auch nicht getestet.
Aber es macht für mich auch keine Sinn. Wenn ich "Createn" wollte, würde ich eine Klasse bauen und keinen Record.

Andere aber ähnliche Frage: Kann man eine Interfacevariable irgendwie darauf testen, ob sie "gebrauchsfertig" ist?

Code: Alles auswählen

type
  ITestInterface = interface
    procedure DoSomething;
  end;
 
var
  I: ITestInterface;
 
begin
....
BinIchCreated(I);

BeniBela
Beiträge: 309
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von BeniBela »

theo hat geschrieben:Andere aber ähnliche Frage: Kann man eine Interfacevariable irgendwie darauf testen, ob sie "gebrauchsfertig" ist?

assigned(i) ?

Die werden wohl automatisch auf nil gesetzt

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

BeniBela hat geschrieben:assigned(i) ?

Die werden wohl automatisch auf nil gesetzt


Nein, werden sie nicht. Siehe oben.
Naja egal. Geht wohl einfach nicht.

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von Socke »

theo hat geschrieben:
BeniBela hat geschrieben:assigned(i) ?

Die werden wohl automatisch auf nil gesetzt


Nein, werden sie nicht. Siehe oben.
Naja egal. Geht wohl einfach nicht.

Dann setz die Variable doch auf nil, sobald sie verfügbar ist!
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Socke hat geschrieben:
theo hat geschrieben:
BeniBela hat geschrieben:assigned(i) ?

Die werden wohl automatisch auf nil gesetzt


Nein, werden sie nicht. Siehe oben.
Naja egal. Geht wohl einfach nicht.

Dann setz die Variable doch auf nil, sobald sie verfügbar ist!


Und wann wäre das innerhalb eines Records?

BeniBela
Beiträge: 309
Registriert: Sa 21. Mär 2009, 17:31
OS, Lazarus, FPC: Linux (Lazarus SVN, FPC 2.4)
CPU-Target: 64 Bit

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von BeniBela »

theo hat geschrieben:Nein, werden sie nicht. Siehe oben./quote]


Hängt wohl davon ab, wo der record herkommt


Zumindest bei Stackrecords habe ich immer nil erhalten

GetMem ist wohl anders


Socke hat geschrieben:Dann setz die Variable doch auf nil, sobald sie verfügbar ist!
[/quote]

Aber mit FillChar

Wenn man einer nicht initialisierten Interfacevariable mit := nil zuweist, ruft es deref auf und stürzt ab

Benutzeravatar
theo
Beiträge: 10497
Registriert: Mo 11. Sep 2006, 19:01

Re: Ohne Nil prüfen ob Objekt erstellt wurde.

Beitrag von theo »

Nochmal.
Die Situation wäre verkürzt so:

Code: Alles auswählen

{$MODESWITCH ADVANCEDRECORDS}
...
TMyRec=Record
private
  fMyIntf: IIrgendWas;
public
  procedure TuWasMitdemInterface;
end;
 


Jetzt möchte ich TuWasMitdemInterface aufrufen, und diese soll das fMyIntf createn, aber nur beim ersten Mal.
Das geht nicht, weil ich nicht prüfen kann, ob das fMyIntf schon created wurde, da fMyIntf anfänglich nicht Nil ist und es auch kein Event gibt, dies selber zu "nillen".

Es geht nicht. Ist OK.

Antworten