开发者

Making a linked-list with generics

I have read how to make a pointer to a normal class and use it inside the class difinition:

type
  PExample = ^TExample;
  TExample = class
    data: I开发者_开发百科nteger;
    next: PExample;
  end;

but how do you do it with templatized parameters? This does not compile with the error Undeclared identifier: 'TExample' on the second line:

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

Changing it to

PExample = ^TExample<T>;

does not fix it.


As you are using a class, you don't need to use a PExample. Classes are already reference types.

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

This should work without the need to declare any pointer types. Pointer types are only required if you work with records (which are value types).

EDIT:

To my surprise I just noticed that this compiles and works in 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.

It does still not solve the problem of defining a general generic pointer type, because this:

PNode<T> = ^TNode<T>;

does not work.


The other answers tell you how to build a generic linked list of classes. If you ever need to build a generic linked list of records, you cannot do so at present:

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

does not compile.

Nor does:

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

I believe that the reason for this is that the single-pass compiler does not support forward declarations of methods. This is actually more of a practical problem for operator overloading than for generics because classes can be used for generic linked lists.


Is it necessary to use a pointer to a class? Using a class reference for your "next" field should work, like this:

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

The "next" field can still be NIL or can be assigned another TExample instance. This seems to negate the need of using a traditional ^ pointer (although you could argue that a reference to a class is also a pointer, just with different syntax).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜