1、 毕 业 设 计 (论文 ) 外 文 文 献 翻 译 专业 学生姓名 班级 学号 指导教师 信息工程学院 1 中文译文 对象的创建和存在时间 从技术角度说, OOP(面向对象程序设计)只是涉及抽象的数据类型、继承以及多形性,但另一些问题也可能显得非常重要。本节将就这些问题进行探讨。 最重要的问题之一是对象的创建及破坏方式。对象需要的数据位于哪儿,如何控制对象的 “ 存在时间 ” 呢?针对这个问题,解决的方案是各异其趣的。 C+认为程序的执行效率是最重要的一个问题,所以它允许程序员 做出 选择。为获 得最快的运行速度,存储以及存在时间可在编写程序时决定,只需将对象放置在堆栈(有时也叫自动或定域变
2、量)或者静态存储区域即可。这样便为存储空间的分配和释放提供了一个优先级。某些情况下,这种优先级的控制是非常有价值的。然而,我们同时也牺牲了灵活性,因为在编写程序时,必须知道对象的准确的数量、存在时间、以及类型。如果要解决的是一个较常规的问题,如计算机辅助设计、仓储管理或者空中交通控制,这一方法就显得太局限了。 第二个方法是在一个内存池中动态创建对象,该内存池亦叫 “ 堆 ” 或者 “ 内存堆 ” 。若采用这种方式,除非进入运行期 ,否则根本不知道到底需要多少个对象,也不知道它们的存在时间有多长,以及准确的类型是什么。这些参数都在程序正式运行时才决定的。若需一个新对象,只需在需要它的时候在内存堆
3、里简单地创建它即可。由于存储空间的管理是运行期间动态进行的,所以在内存堆里分配存储空间的时间比在堆栈里创建的时间长得多(在堆栈里创建存储空间一般只需要一个简单的指令,将堆栈指针向下或向下移动即可)。由于动态创建方法使对象本来就倾向于复杂,所以查找存储空间以及释放它所需的额外开销不会为对象的创建造成明显的影响。除此以外,更大的灵活性对于常规编程问 题的解决是至关重要的。 C+允许我们决定是在写程序时创建对象,还是在运行期间创建,这种控制方法更加灵活。大家或许认为既然它如此灵活,那么无论如何都应在内存堆里创建对象,而不是在堆栈中创建。 但还要考虑另外一个问题,亦即对象的 “ 存在时间 ” 或者 “
4、 生存时间 ”( Lifetime)。若在堆栈或者静态存储空间里创建一个对象,编译器会判断对象的持续时间有多长,到时会自动 “ 破坏 ” 或者 “ 清除 ” 它。程序员可用两种方法来破坏一个对象:用程序化的方式决定何时破坏对象,或者利用由运行环境提供的一种 “ 垃圾收集器 ” 特性,自动寻找那些不 再使用的对象,并将其清除。当然,垃圾收集器显得方便得多,但要求所有应用程序都必须容忍垃圾收集器的存在,并能默许随垃圾收集带来的额外开销。但这并不符合 C+语言的设计宗旨,所以未能包括到 C+里。但 Java 确实提供了一个垃圾收集器( Smalltalk 也有这样的设计;尽管 Delphi 默认为没
5、有垃圾收集器,但可选择安装;而 C+亦可使用一2 些由其他公司开发的垃圾收集产品)。 本节剩下的部分将讨论操纵对象时要考虑的另一些因素。 1、 集合与继承器 针对一个特定问题的解决,如果事先不知道需要多少个对象,或者它们的持续时间 有多长,那么也不知道如何保存那些对象。既然如此,怎样才能知道那些对象要求多少空间呢?事先上根本无法提前知道,除非进入运行期。 在面向对象的设计中,大多数问题的解决办法似乎都有些轻率 只是简单地创建另一种类型的对象。用于解决特定问题的新型对象容纳了指向其他对象的句柄。当然,也可以用数组来做同样的事情,那是大多数语言都具有的一种功能。但不能只看到这一点。这种新对象通常叫
6、 “ 集合 ” (亦叫一个 “ 容器 ” ,但 AWT在不同的场合应用了这个术语,所以本书将一直沿用 “ 集合 ” 的称呼。在需要的时候,集合会自动扩充自己,以便适应我 们在其中置入的任何东西。所以我们事先不必知道要在一个集合里容下多少东西。只需创建一个集合,以后的工作让它自己负责好了。 幸运的是,设计优良的 OOP 语言都配套提供了一系列集合。在 C+中,它们是以 “ 标准模板库 ” ( STL)的形式提供的。 Object Pascal 用自己的 “ 可视组件库 ” ( VCL)提供集合。 Smalltalk 提供了一套非常完整的集合。而 Java 也用自己的标准库提供了集合。在某些库中,
7、一个常规集合便可满足人们的大多数要求;而在另一些库中(特别是 C+的库),则面向不同的需求提供了不同类型的集合。例如, 可以用一个矢量统一对所有元素的访问方式;一个链接列表则用于保证所有元素的插入统一。所以我们能根据自己的需要选择适当的类型。其中包括集、队列、散列表、树、堆栈等等。 所有集合都提供了相应的读写功能。将某样东西置入集合时,采用的方式是十分明显的。有一个叫 “ 推 ” ( Push)、 “ 添加 ” ( Add)或其他类似名字的函数用于做这件事情。但将数据从集合中取出的时候,方式却并不总是那么明显。如果是一个数组形式的实体,比如一个矢量( Vector),那么也许能用索引运算符或函
8、数。但在许多情况下,这样做往往会无功而返。此外,单选定 函数的功能是非常有限的。如果想对集合中的一系列元素进行操纵或比较,而不是仅仅面向一个,这时又该怎么办呢? 办法就是使用一个 “ 继续器 ” ( Iterator),它属于一种对象,负责选择集合内的元素,并把它们提供给继承器的用户。作为一个类,它也提供了一级抽象。利用这一级抽象,可将集合细节与用于访问那个集合的代码隔离开。通过继承器的作用,集合被抽象成一个简单的序列。继承器允许我们遍历那个序列,同时毋需关心基础结构是什么 换言之,不管它是一个矢量、一个链接列表、一个堆栈,还是其他什么东西。这样一来,我们就可以灵活地改 变基础数据,不会对程序里的代码造成干扰。 Java 最开始(在 1.0 和 1.1 版中)提供的是一个标准继承器,名为 Enumeration(枚举),为它的所有集合类提供服务。 Java 1.2 新增一个更复杂的集合库,其中包含了一个名为 Iterator 的继承器,可以做比老式的 Enumeration