计算机二级

3773考试网计算机等级考试计算机二级正文

探析泛型编程在非C++语言中的实现

来源:fjzsksw.com 2010-7-29 9:27:00

 

GP(Generic Programming,泛型编程)号称编程思想的又一次革命。但是,在论述GP的资料中,一般都是以C++语言为基础来讨论。那么,GP是否可以在其它的编程语言中实现呢?这是一直在思考的一个问题,因为水平有限和资料匮乏,收获甚微。现将一些不成熟的想法整理出来,请方家不吝指教。

以Delphi为例(Java的情况与此类似,可参照),讨论GP的另一种实现思路。代码是随手写出的,未经验证。

根据的理解,实现GP的关键之处,在于实现ADT(Abstract Data Type,抽象数据类型)。只有实现了ADT,才能够将具体的数据类型与通用的算法分离开来。

在C++中,ADT的存储是通过模板来实现的。举一个最简单的栈的例子(没有给出实现部分):

template class Type class Stack{

public:

void Push(const Type &item);

Type Pop;

...

}

栈的应用:

Stack int s;

int data;

data = 1;

s.Push(data); file://入栈

int out;

out = s.Pop; file://出栈

通过建立一个int类型的Stack对象,实现了对int类型数据的存储。

但是,在Delphi/Java中,并没有模板这种机制。那么如何实现ADT呢?与C++不同的是,Delphi/Java的类继承体系是单根结构的,也就是说,在Delphi中,所有的class都通过编译器强制而保证成为TObject的子类(Java中是Object)。这个TObject可以看成是一切类的最高层次的抽象。那么,是否可以认为Delphi/Java中已经先天地提供了对ADT的支持呢?

试着用这种思路建立一个栈:

TStack = class

public

procedure Push(item:TObject);

function Pop:TObject;

...

end;

这个TStack类针对TObject类型的对象进行操作。但是,这个类还不能立即应用,因为在Delphi中,简单数据类型并不是对象。所以必须再建立一个自定义的数据类型。下面建立了只有一个integer成员的自定义数据类型:

TADT = class

public

data:integer;

end;

再来看栈的应用:

var

stack:TStack;

adt1,adt2:TADT;

begin

stack := TStack.create;

adt1 := TADT.create;

stack.Push(adt1); file://入栈

adt2 := stack.Pop as TADT; file://出栈

stack.free;

这样就完成了对ADT对象的存储。必须注意到,在入栈时,是将adt对象直接入栈的,因为TStack类是对TObject进行操作,由于Delphi的单根结构,可以将任何类型的对象赋给TObject类型的变量。但是,出栈时,返回的也是一个TObject的变量,因此必须用as完成一次向下映射。同样由于单根结构,Delphi/Java提供了对RTTI的强大支持,因此这种向下映射是轻而易举的事情。但是,毫无疑问,RTTI在效率上有所损失。

 

 

触屏版 电脑版
3773考试网 琼ICP备12003406号-1