理解Pascal等效于C / C ++类型的前向声明

时间:2015-10-21 13:25:13

标签: pascal freepascal forward-declaration

我知道来自C / C ++的前向声明,我知道它们的原因和使用方法。当改为Pascal时,我错过了这个功能的真正等价物。如果我尝试声明我正在使用的类型(通过指针)在另一种类型中,如此,

type
  TBRec = record
    FA: ^TARec;
  end;

  TARec = record
    FB: ^TBRec;
  end;

Pascal(事实上,我尝试使用Free Pascal)隐式地从标识符前面的^中推断出不完整的类型(被视为不完整类型)。但是这种技术仅限于相同类型定义部分的范围。

是否可以将相关的类型定义放入单独的单元中,以及如何执行此操作?

编辑:我错误地为class写了TARec,在两种情况下都应该是record

2 个答案:

答案 0 :(得分:3)

Pascalish做这些事情的方法是:

type
  // Forward declarations of pointers
  PARec = ^TARec;
  PBRec = ^TBRec;

  TBRec = record
    FA: PARec;
  end;

  TARec = record
    FB: PBRec;
  end;

Read more here

如果所有声明都在同一单元且type部分相同,则可以使用。

如果声明以不同的单位拆分,可以使用无类型指针,显式类型转换和循环单位引用来解决:

unit a;

interface

  PARec = ^TARec;
  TARec = record
    FB: Pointer; // Untyped pointer
  end;  

implementation

uses
  b; // Cyclic unit reference in the implementation section, see unit b below

procedure foo;
var
  ra: PARec;
begin
  ra := New(PARec);
  ra^.FB := New(PBRec);
  PBRec(ra^.FB)^... // PBRec is declared in the b unit
  // or
  TBRec(ra^.FB^)...
end;

end.
unit b;

interface

uses
  a;

type
  PBRec = ^TBRec;
  TBRec = record
    FA: PARec; // We can use PARec type because it already known here
  end;

答案 1 :(得分:2)

您可以通过定义空类或接口来定义前向声明。您可以在同一类型声明部分中稍后指定类型,但您已经可以在转发声明和指定声明之间使用它。

type
  TARec = class; // <-- Forward declaration

  TBRec = record
    FA: ^TARec;
  end;

  TARec = class
  public
    FB: ^TBRec;
  end;

因此无法在文件A.Pas中声明转发类型并在文件B.pas中指定它