泛型和非泛型顶点类型的图类

时间:2014-01-21 22:21:54

标签: delphi generics

已经讨论了带有可选数据字段的顶点类SKIP GENERIC PARAMETER ON DEMAND;对我来说最好的解决方案是这样的:

type
  TVertex = class
  public
    Name: String;
    OutputAttributes: TVertexOutputAttributes;
    Marker: Boolean;
  end;


type
  TVertex<T> = class(TVertex)
  public
    Data: T; // User-defined data attribute
  end;

现在写连接图类时,我想出了另一个问题:

TGraph = Class
  private
  Vertices: TObjectList<TVertex>;
  ....
  function addVertex(u: TVertex): Integer;
  function removeVertex(u: TVertex): TVertex;
 end;

所有函数现在请求我的顶点类Tvertex的非泛型版本。扩展我的Graph类以使用两个顶点类定义(通用Tvertex和非通用一个TVertex)的最佳方法是什么?我尝试了以下代码但没有成功。

//  a generic class working with 2 Tvertex class definitions ... 
//  this code does npot work :-(  
TGraph<MyVertexType> = Class
  private
  Vertices: TObjectList<MyVertexType>;
  ....
  function addVertex(u: MyVertexType): Integer;
  function removeVertex(u: MyVertexType): MyVertexType;
 end;

2 个答案:

答案 0 :(得分:1)

您当前的代码无法编译,因为您使用的TObjectList<T>要求T成为一个类。没有强制执行的约束。所以你可以添加那个约束:

type
  TGraph<MyVertexType: class> = class
    FVertices: TObjectList<MyVertexType>;
    ...
  end;

我确实想知道你是否已经完全考虑了顶点的终身所有权。使用TObjectList<T>意味着您希望列表拥有对象并在从列表中删除它们时将其销毁。在这种情况下

function removeVertex(u: MyVertexType): MyVertexType;

没有意义。

请注意,上面的定义不允许图表类知道MyVertexType的功能,而不仅仅是它是一个类。所以也许你应该将MyVertexType限制为一个顶点:

type
  TGraph<MyVertexType: TVertex> = class
    ...
  end;

这将允许图形容器在其成员上调用顶点方法。

答案 1 :(得分:-1)

type
  TVertex = class
  public
    Name: String;
    OutputAttributes: TVertexOutputAttributes;
    Marker: Boolean;
  end;

  TIntVertex = class(TVertex)
  public
    Data: Integer;
  end;

  TSomethingElseVertex = class(TVertex)
  public
    Data: TSomethingElse;
  end;

TGraph = class(TObjectList<TVertex>)
// any additional methods
end;

...

var
  Graph: TGraph;
  Vertex: TVertex;

...

Vertex := TIntVertex.Create;
Graph.Add(Vertex);
Vertex := Graph.Last;
if (Vertex is TIntVertex) then
  (Vertex as TIntVertex).Data := 42;