如何在Object Pascal中实现类似C++中的模板

有时候,我们需要C++的模版,具体的类型在后期才能确定。
比如下面一个例子:
在用于遍历的Iterator模式中,有一个迭代器基类,大体如下:
TwhhIteratorBase = class
public
procedure First; abstract; virtual;
procedure Next; abstract; virtual;
//是否遍历完毕
procedure IsDone; abstract; virtual;
//返回当前元素.由于这时基类,返回TObject类型。
function CurrentItem: TObject; abstract; virtual;
end;

然后再一个具体应用中,比如一个文档列表对象,其对应的迭代器是从这个迭代器基类继承过来,前面三个方法都比较容易直接覆盖(override);
TwhhDocListIterator = class
private
FiCurrent: Integer;
public
procedure First; override;
procedure Next; override;
//是否遍历完毕
procedure IsDone; override;
//如果是Override,则返回值必须为TObject,跟父类声明一致。
//当我多么希望是返回的类型是TDoc,格式如下
//function CurrentItem:TDoc
//我在使用这个迭代器的时候就不需要进行类型转换
//这在C++中,运用模版是可以达到的。
function CurrentItem: TObject; override;
end;
希望大家能够积极参与,如何能够实现类似模板的思路。



[930 byte] By [WuHeHai-风之影] at [2008-6-10]
# 1
没有
你可以用Variant
artman-TheFinal. at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 2
Sorry.由于匆忙,前面的InDone方法的声明更改为如下:
function IsDone: Boolean;
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 3
多谢artman的参与。
Variant是一个变体,可以保存任何值。但是我需要的是能够在子类中
返回所需要类型的对象。Variant和对象之间是不能直接转换的啊。
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 4
you can use TObject.
# 5
help up
S_caijing-star at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 6
Object pascal中没有模板,你可以把参数设置为TObject(或其它基类),运行时用RTTI去检验类型.
plainsong-短歌 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 7
建议使用TObject
netlib-河外孤星 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 8
首先,谢谢各位的参与。
我突然有一个想法,是否把CurrentItem作为属性
然后在子类中重新定义这个属性的类型。如:
TwhhIteratorBase = class
public
//返回当前元素.由于这时基类,返回TObject类型。
property CurrentItem: TObject;
end;

TwhhDocListIterator = class
public
//可以在子类重新定义这个属性的类型
property CurrentItem: TDoc read GetCurrentItem;
end;
这样的话,不管那个层次的迭代器,都这个属性CurrentItem。但在子类中
这个属性的类型可以不同。
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 9
这和继承有什么区别吗?你还是要为每个子类声明和书写代码。
artman-TheFinal. at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 10
那不一样,这个基类已经定义访问这个类的接口。我可以在其他地方中使用这个迭代器时,就可以直接使用这个接口了。无需知道这个接口是如何具体实现了。比如就这个迭代器,经常有对应的Traverser类。Traverser类中有一个迭代器的实例,就可以直接使用这个迭代器了,无需知道这个迭代器是如何实现。代码如下:
TTraverser = class
protected
function ProcessItem(AobjItem: TObject): Boolean;
function CreateIterator: TwhhIterator;
public
function Traverser: Boolean;
end;

下面是实现代码:
function TTraverser.CreateIterator: TwhhIterator;
begin
Result := TwhhIterator.Create;
end;

function TTraverser.ProcessItem(AobjItem: TObject): Boolean;
begin
Result := True;
end;

function TTraverser.Traverser: Boolean;
var
objIterator: TifoIterator;
begin
Result := False;
objIterator := CreateIterator;
//通过Iterator遍历,然后对所有Item进行ProcessItem操作。
objIterator.First;
while not objIterator.IsDone do begin
if not ProcessItem(objItem.CurrentItem) then begin
Exit;
end;
objIterator.Next;
end;
Result := True;
end;
这个Traverser类就是通过迭代器的遍历,对Item进行ProcessItem操作。完成对所有Item的操作。而且这个类很容易进行子类化,从而实现对Item进行不同操作的目的,重用性高。但在Traverser类不一定需要Iterator类具体是如何实现,就可以完成了。而且是什么Iterator子类实例化,可以在子类对CreateIterator覆盖后期达到。

WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 11
你是对的,使用OO设计模式的一些技巧可以代替C++模板的部分功能.这样在子类中就不必重写大部分的有关算法的代码.
在这个例子里,要为每个子类写GetCurrentItem的代码,当然.
要是想同使用C++模板那么简单是不可能的.
artman-TheFinal. at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 12
要写在子类中写GetCurrentItem代码那是必然,只是想
在子类中能够制定Item的类型,同时又不会破坏基类的接口。
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 13
提一提
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 14
UP.
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...
# 15
不只哪位还有高见?
等会我就要结了。
WuHeHai-风之影 at 2007-10-27 > top of Msdn China Tech,Delphi,语言基础/算法/系统设计...