Delphi循环单位参考

时间:2020-01-28 15:43:56

标签: delphi

我在上课之间存在循环引用的问题。这是错误:

[dcc32致命错误] StackWeb.MessageClassHelper.pas(5):F2047对“ StackWeb.MessageClass”的循环单元引用

我想在不同的单元中使用这两个类。

我该如何解决?

unit StackWeb.MessageClass;

interface

uses
  StackWeb.ChatItemClass,

type    
  TMessageClass = class(TCardDefault)
  private
    FChat : TChatItemClass;
  public
    property chat : TChatItemClass read FChat write FChat;
  end;

unit StackWeb.ChatItemClass;

interface

uses
  StackWeb.MessageClass;

type    
  TChatItemClass = class(TClassStandardList<TMessageClass>)
  private
    FMessages : TArray<TMessageClass>;
  public
    property messages : TArray<TMessageClass> read FMessages write FMessages;
  end;

1 个答案:

答案 0 :(得分:1)

TMessageClass类的声明不需要知道如何声明TChatItemClass类的细节,只需知道它是一个类类型,所以使用转发声明,以打破两个interface部分的循环单位依赖性,例如:

unit StackWeb.MessageClass;

interface

{uses
  StackWeb.ChatItemClass;}

type
  TChatItemClass = class; // <-- HERE

  TMessageClass = class(TCardDefault)
  private
    FChat : TChatItemClass;
  public
    property chat : TChatItemClass read FChat write FChat;
  end;

implementation

uses
  StackWeb.ChatItemClass; // <-- MOVED HERE

...

end.
unit
  StackWeb.ChatItemClass;

interface

uses
  StackWeb.MessageClass;

type
  TChatItemClass = class(TClassStandardList<TMessageClass>)
  private
    FMessages : TArray<TMessageClass>;
  public
    property messages : TArray<TMessageClass> read FMessages write FMessages;
  end;

...

end.

Delphi的文档中实际上涵盖了这种情况:

Classes and Objects (Delphi): Forward Declarations and Mutually Dependent Classes

如果类类型的声明以单词class和分号结尾-也就是说,如果其形式为

type className = class;

class一词之后没有祖先或类成员,则它是一个前向声明。前向声明必须通过相同类型声明部分中相同类的定义声明来解决。换句话说,在前向声明及其定义声明之间,除其他类型声明外,什么都不会发生。

转发声明允许相互依赖的类。例如:

type
  TFigure = class; // forward declaration
  TDrawing = class
    Figure: TFigure;
    // ...
  end;

  TFigure = class // defining declaration
    Drawing: TDrawing;
    // ...
  end; 

不要将前向声明与从System.TObject派生的类型的完整声明混淆,而无需声明任何类成员。

type
  TFirstClass = class; // this is a forward declaration

  TSecondClass = class // this is a complete class declaration
  end;

  TThirdClass = class(TObject); // this is a complete class declaration
相关问题