Составление связного списка с генериками - PullRequest
0 голосов
/ 18 марта 2011

Я прочитал, как создать указатель на обычный класс и использовать его внутри определения класса:

type
  PExample = ^TExample;
  TExample = class
    data: Integer;
    next: PExample;
  end;

а как вы делаете это с шаблонными параметрами? Это не компилируется с ошибкой Undeclared identifier: 'TExample' во второй строке:

type
 PExample = ^TExample;
 TExample<T> = class
   data: T;
   next: PExample;
 end;

Изменение на

PExample = ^TExample<T>;

не исправляет это.

Ответы [ 3 ]

4 голосов
/ 18 марта 2011

Поскольку вы используете класс, вам не нужно использовать PExample.Классы уже являются ссылочными типами.

 TExample<T> = class
   data: T;
   next: TExample<T>;
 end;

Это должно работать без необходимости объявления каких-либо типов указателей.Типы указателей требуются, только если вы работаете с записями (которые являются типами значений).

EDIT:

К моему удивлению, я только что заметил, что это компилируется и работает в Delphi XE:

program Project;

{$APPTYPE CONSOLE}

type
  TNode<T> = record
    Next: ^TNode<T>;
    Data: T;
  end;

var
  Node1, Node2: TNode<Integer>;

begin
  Node1.Next := @Node2;
  Node1.Data := 1;
  Node2.Next := nil;
  Node2.Data := 2;

  WriteLn(Node1.Data);
  WriteLn(Node1.Next.Data);
end.

Это все еще не решает проблему определения общего универсального типа указателя, потому что это:

PNode<T> = ^TNode<T>;

не работает.

2 голосов
/ 18 марта 2011

В других ответах рассказывается, как создать общий связанный список классов.Если вам когда-либо понадобится создать общий связанный список записей, вы не можете сделать это в настоящее время:

type
  PNode<T> = ^TNode<T>;
  TNode<T> = record
  public
    Next: PNode;
  end;

не компилируется.

И не делает:

type
  TNode<T> = record
  type
    PNode = ^TNode;
  public
    Next: PNode;
  end;

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

1 голос
/ 18 марта 2011

Нужно ли использовать указатель на класс? Использование ссылки на класс для вашего «следующего» поля должно работать следующим образом:

type
 TExample<T> = class
   data: T;
   next: TExample<T>;
 end;

Поле "next" может по-прежнему иметь значение NIL или ему может быть назначен другой экземпляр TExample. Это, кажется, сводит на нет необходимость использования традиционного указателя ^ (хотя можно утверждать, что ссылка на класс также является указателем, только с другим синтаксисом).

...