F2047 Circular unit reference

[亡魂溺海] 提交于 2021-02-05 07:12:06

问题


i working with overload of operator, and i have this situation, fra a side:

unit _TIns;

interface

uses
  _TExtract;

type
  TIns = record
  private type
    TInsArray = array [1..90] of Boolean;
  var
    FInsArray: TInsArray;
  public
    class operator Implicit(const Value: TExtract): TIns;
    class operator Implicit(const Value: TIns): TExtract;
  end;

implementation
  // Code
end.

and, from other side:

unit _TExtract;

interface

uses
  _TIns;

type
  TExtract = record
  private type
    TExtractEnum = 1 .. 90;
  var
    FExtractEnum: TExtractEnum;
  public
    class operator Implicit(const Value: Integer): TExtract;
    class operator Implicit(const Value: TExtract): Integer;
    class operator In(A: TExtract; B: TIns) : Boolean;
  end;

implementation
  // Code
end.

Of course, i have understood where is the problem, and it is that both unit call other. But not have understood as solve it. If i try to define it in same unit the first TExtract not find TIns, or otherwise TIns not find TExtract. I can delete dependency and solve so, only if not exist solution, but i would use this data type for both. Thanks very much for help and good new year to all.


回答1:


You have two circular reference issues. Firstly you are declaring two units which each refer to the other in the interface section. That can be solved a variety of ways. For now For now I am going to ignore that issue and focus on the other circular reference problem. In order to do so I'm going to assume all code appears in the same unit.

The more pressing circular reference problem is that TIns refers to TExtract and vice versa. In order to break this particular circularity you would need to introduce a forward reference, just as is commonly done with classes. But it turns out that forward references cannot be made for record types.

Whilst forward references are possible for class types, there is a fundamental difference between class types and record types. Record types are value types and class types are reference types. The current implementation of the Delphi compiler does not support forward references for value types.

The solution to your problem is to move the operators that refer to both types to whichever record is declared last. For example:

TIns = record
private type
  TInsArray = array [1..90] of Boolean;
var
  FInsArray: TInsArray;
end;

TExtract = record
private type
  TExtractEnum = 1 .. 90;
var
  FExtractEnum: TExtractEnum;
public
  class operator Implicit(const Value: TExtract): TIns;
  class operator Implicit(const Value: TIns): TExtract;
  class operator Implicit(const Value: Integer): TExtract;
  class operator Implicit(const Value: TExtract): Integer;
  class operator In(A: TExtract; B: TIns) : Boolean;
end;

If you wish to retain two separate units then do it like this:

  1. Put TIns in the unit _TIns.
  2. Do not use _TExtract from _TIns.
  3. Put TExtract in the unit _TExtract.
  4. Use _TIns from the interface section of _TExtract.

Like this:

unit _TIns;

interface

type
  TIns = record
  private type
    TInsArray = array [1..90] of Boolean;
  var
    FInsArray: TInsArray;
  end;

implementation

end.

 

unit _TExtract;

interface

uses
  _TIns;

type
  TExtract = record
  private type
    TExtractEnum = 1 .. 90;
  var
    FExtractEnum: TExtractEnum;
  public
    class operator Implicit(const Value: TExtract): TIns;
    class operator Implicit(const Value: TIns): TExtract;
    class operator Implicit(const Value: Integer): TExtract;
    class operator Implicit(const Value: TExtract): Integer;
    class operator In(A: TExtract; B: TIns) : Boolean;
  end;

implementation
  // Code
end.


来源:https://stackoverflow.com/questions/8644014/f2047-circular-unit-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!