ho dato una risposta precedente, ma dopo un po 'di pensiero e graffi ho trovato un modo migliore per risolvere il problema di riferimento circolare. Ecco la mia prima unità che hanno bisogno di un puntatore su un oggetto TB definire in unità B.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, b, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
FoB: TB;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
FoB := TB.Create(Self);
showmessage(FoB.owner.name);
end;
end.
Ecco il codice dell'Unità B dove la tubercolosi ha un puntatore su TForm1.
unit B;
interface
Uses
dialogs, Forms;
type
TForm1 = class(TForm);
TB = class
private
FaOwner: TForm1;
public
constructor Create(aOwner: TForm);
property owner: TForm1 read FaOwner;
end;
implementation
uses unit1;
Constructor TB.create(aOwner: TForm);
Begin
FaOwner := TForm1(aOwner);
FaOwner.Left := 500;
End;//Constructor
end.
E qui perché compila. La prima unità B dichiara l'uso dell'unità 1 nella sezione dell'implementazione. Risolvere immediatamente l'unità di riferimento circolare tra Unità1 e Unità B.
Ma per consentire a Delphi di compilare, ho bisogno di dargli qualcosa da masticare sulla dichiarazione di FaOwner: TForm1. Quindi, aggiungo il nome della classe stub TForm1 che corrisponde alla dichiarazione di TForm1 in Unità1. Successivamente, quando arriva il momento di chiamare il costruttore, TForm1 è in grado di passare se stesso ha il parametro. Nel codice costruttore, devo digitare il parametro aOwner su Unit1.TForm1. E voilà, FaOwner il suo set per puntare sulla mia forma.
Ora, se la classe TB deve utilizzare FaOwner internamente, non è necessario convertirla ogni volta da a Unit1.TForm1 perché entrambe le dichiarazioni sono uguali. Si noti che è possibile impostare la dichiarazione di al costruttore per
Constructor TB.create(aOwner: TForm1);
ma quando TForm1 chiamerà il costruttore e superare se stessa ha un parametro, è necessario typecast ha b.TForm1. Altrimenti Delphi genererà un errore che dice che entrambi TForm1 non sono compatibili. Quindi ogni volta che chiami la TB.costruttore dovrai digitare per l'appropriato TForm1. La prima soluzione, usando un antenato comune, è la sua migliore. Scrivi il typecast una volta e dimenticalo.
Dopo averlo pubblicato, mi sono reso conto che ho fatto un errore dicendo che entrambi TForm1 erano identici. Non sono Unit1.TForm1 ha componenti e metodi sconosciuti a B.TForm1. La TB lunga non ha bisogno di usarli o è solo necessario usare la comunanza data da TForm che stai bene. Se è necessario chiamare qualcosa di particolare a UNit1.TForm1 da TB, sarà necessario convertirlo in Unit1.TForm1.
Ho provato e testato con Delphi 2010 e ha compilato e lavorato.
Spero che ti aiuti e ti risparmi un po 'di mal di testa.
+1. IMHO non c'è bisogno di esitare qui. –
+1 Sono con l'onorevole Gerhardt. Non c'è bisogno di esitare. –
+1 Un'unità "AppTypes.pas" è una cosa molto comune nelle app Delphi. –