F2047 Ссылка на круглую единицу - PullRequest
2 голосов
/ 27 декабря 2011

я работаю с перегрузкой оператора, и у меня такая ситуация со стороны:

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.

, а с другой стороны:

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.

Конечно, я понял, в чем проблема, и то, что оба устройства вызывают другие. Но не поняли как это решить. Если я пытаюсь определить его в том же модуле, первый TExtract не находит Tins, или иначе Tins не находит TExtract. Я могу удалить зависимость и решить ее, только если не существует решения, но я бы использовал этот тип данных для обоих. Большое спасибо за помощь и хорошего Нового года всем.

1 Ответ

5 голосов
/ 27 декабря 2011

У вас есть две проблемы с круговыми ссылками.Во-первых, вы объявляете два блока, каждый из которых ссылается на другой в разделе интерфейса.Это может быть решено различными способами.На данный момент Пока я собираюсь игнорировать эту проблему и сосредоточиться на другой круговой ссылочной проблеме.Для этого я предполагаю, что весь код отображается в одном и том же блоке.

Более насущная проблема с циклической ссылкой состоит в том, что TIns относится к TExtract и наоборот.Для того, чтобы разорвать эту конкретную цикличность, вам необходимо ввести прямую ссылку, как это обычно делается с классами.Но оказывается, что прямые ссылки не могут быть сделаны для record типов.

Хотя прямые ссылки возможны для типов классов, между типами классов и типами записей есть принципиальное различие.Типы записей являются типами значений, а типы классов являются ссылочными типами.Текущая реализация компилятора Delphi не поддерживает прямые ссылки для типов значений.

Решение вашей проблемы состоит в том, чтобы переместить операторы, которые ссылаются на оба типа, в ту запись, которая объявлена ​​последней.Например:

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;

Если вы хотите сохранить две отдельные единицы, сделайте это следующим образом:

  1. Поместите TIns в единицу _TIns.
  2. Do not use _TExtract from _TIns.
  3. Введите TExtract в устройстве _TExtract.
  4. Используйте _TIns в разделе интерфейса _TExtract.

Вот так:

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.
...