Zirkuläre Referenzen

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Zirkuläre Referenzen

Beitrag von fliegermichl »

Hallo zusammen,

gibt es in Free Pascal mittlerweile eigentlich eine Möglichkeit, zirkuläre Referenzen zwischen verschiedenen Klassen mit separaten Quellcode Dateien zu realisieren?

Code: Alles auswählen

type
 THund = class;  	// forward declaration
 
 TBesitzer = class 
 private
  fHund : THund;
 end;
 
 THund = class
 private
  fBesitzer : TBesitzer;
 end;
So lässt sich das aktuell realisieren aber eben nur innerhalb der gleichen Quellcode Datei.

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

Re: Zirkuläre Referenzen

Beitrag von theo »

Was heisst für dich Quellcode-Datei?

Bei einer Unit ist mir das nicht bekannt, bin aber vielleicht nicht up-to-date.
Aber du kannst jeden Code-Fetzen in einer separaten Datei speichern und mit {$i test.inc} einbinden.

Benutzeravatar
Winni
Beiträge: 1577
Registriert: Mo 2. Mär 2009, 16:45
OS, Lazarus, FPC: Laz2.2.2, fpc 3.2.2
CPU-Target: 64Bit
Wohnort: Fast Dänemark

Re: Zirkuläre Referenzen

Beitrag von Winni »

Hi!

Weil Du die beiden Klassen jeweils im Interface haben musst, geht es nicht, das auf zwei Units zu verteilen.
Aber wie gesagt: Bei Include-Files gibt es keine Beschränkung bei Anzahl und Länge. Manche Units in der RTL bestehen fast nur aus Include-Files.

Für andere Fälle als Deinen - z.B . für schlechte Programmierung - ist Folgendes erlaubt:

Unit A uses Unit B - im Interface.
und
Unit B uses Unit A - nur in der Implementation

Kann man schön viel Mist mit bauen .

Winni

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

Re: Zirkuläre Referenzen

Beitrag von Warf »

Müsste so gehen (ungetestet), im interface machst du eine foward deklaration, und im implementation dann ein eigenes uses:

Code: Alles auswählen

// BesitzerUnit.pas
interface

uses HundUnit; // ganz normales include

type
  TBesitzer = class
    Hund: THund;
  end;
  
// HundUnit.pas
interface

type
  TBesitzer = class; // fowrard deklaration
  
  THund = class
    Besitzer: TBesizer;
  end;
  
implementation
uses BesitzerUnit; // implementation uses um zirkuläre referenzen zu vermeiden

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Zirkuläre Referenzen

Beitrag von marcov »

Nein das geht nicht. Forward Referenzen sollen im selben Unit definiert werden. Nicht importiert.

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Zirkuläre Referenzen

Beitrag von fliegermichl »

Ich bin echt beeindruckt, wie gut das mit den include Dateien funktioniert.

Ich hab folgendes probiert:

Code: Alles auswählen

// main.pas
unit main;
type
  TSecond = class;

  { TFirst }

  TFirst = class
  private
    fSecond : TSecond;
  public
    //function  TellMyName : string;
    procedure SetSecond(aSecond : TSecond);
  end;

  { TSecond }

  TSecond = class
  private
    fFirst : TFirst;
  public
    //function  TellMyName : string;
    procedure SetFirst(aFirst : TFirst);
  end;

implementation

{$i first.inc}
{$i second.inc}

end.
Wenn man nun first.inc und second.inc erzeugt, den Cursor auf "procedure SetSecond(aSecond : TSecond);" und Ctrl+Shift+C drückt, wird die Implementation der Methode
zunächst in main.pas eingefügt. Verschiebt man diese implementation dann in die Datei first.inc, entfernt den Kommentar bei "TellMyName" und drückt wiederum Ctrl+Shift+C, so wird die weitere Implementation automatisch in der first.inc erzeugt und die Eingabe springt dahin.

Gleiches Verhalten bei TSecond.

Mit Ctrl+Shift+Cursor hoch kann man wie gewohnt zwischen interface und implementation der Methoden hin und herwechseln.
Ein weiterer Vorteil besteht darin, daß man z.B. Systemspezifische Implementationen in separaten include Files halten kann.

Damit kann man problemlos jede Klasse in eigenen Quellcode Dateien halten und die Zeiten, wo ich Quellcodedateien mit hunderttausend und mehr Zeilen Code hatte sind vorbei.

Antworten