返回介绍

10.7 抽象数据类型

发布于 2024-10-08 23:14:08 字数 2529 浏览 0 评论 0 收藏 0

Stock 类非常具体。然而,程序员常常通过定义类来表示更通用的概念。例如,就实现计算机专家们所说的抽象数据类型(abstract data type,ADT)而言,使用类是一种非常好的方式。顾名思义,ADT 以通用的方式描述数据类型,而没有引入语言或实现细节。例如,通过使用栈,可以以这样的方式存储数据,即总是从堆顶添加或删除数据。例如,C++程序使用栈来管理自动变量。当新的自动变量被生成后,它们被添加到堆顶;消亡时,从栈中删除它们。

下面简要地介绍一下栈的特征。首先,栈存储了多个数据项(该特征使得栈成为一个容器——一种更为通用的抽象);其次,栈由可对它执行的操作来描述。

  • 可创建空栈。
  • 可将数据项添加到堆顶(压入)。
  • 可从栈顶删除数据项(弹出)。
  • 可查看栈否填满。
  • 可查看栈是否为空。

可以将上述描述转换为一个类声明,其中公有成员函数提供了表示栈操作的接口,而私有数据成员负责存储栈数据。类概念非常适合于 ADT 方法。

私有部分必须表明数据存储的方式。例如,可以使用常规数组、动态分配数组或更高级的数据结构(如链表)。然而,公有接口应隐藏数据表示,而以通用的术语来表达,如创建栈、压入等。程序清单 10.10 演示了一种方法,它假设系统实现了 bool 类型。如果您使用的系统没有实现,可以使用 int、0 和 1 代替 bool、false 和 true。

程序清单 10.10 stack.h

在程序清单 10.10 所示的示例中,私有部分表明,栈是使用数组实现的;而公有部分隐藏了这一点。因此,可以使用动态数组来代替数组,而不会改变类的接口。这意味着修改栈的实现后,不需要重新编写使用栈的程序,而只需重新编译栈代码,并将其与已有的程序代码链接起来即可。

接口是冗余的,因为 pop( ) 和 push( ) 返回有关栈状态的信息(满或空),而不是 void 类型。在如何处理超出栈限制或者清空栈方面,这为程序员提供了两种选择。他可以在修改栈前使用 isempty( ) 和 isfull( ) 来查看,也可以使用 push( ) 和 pop( ) 的返回值来确定操作是否成功。

这个类不是根据特定的类型来定义栈,而是根据通用的 Item 类型来描述。在这个例子中,头文件使用 typedef 用 Item 代替 unsigned long。如果需要 double 栈或结构类型的栈,则只需修改 typedef 语句,而类声明和方法定义保持不变。类模板(参见第 14 章)提供了功能更强大的方法,来将存储的数据类型与类设计隔离开来。

接下来需要实现类方法,程序清单 10.11 提供了一种可行的实现。

程序清单 10.11 stack.cpp

默认构造函数确保所有栈被创建时都为空。pop( ) 和 push( ) 的代码确保栈顶被正确地处理。这种保证措施是 OOP 更可靠的原因之一。假设要创建一个独立数组来表示栈,创建一个独立变量来表示栈顶索引。则每次创建新栈时,都必须确保代码是正确的。没有私有数据提供的保护,则很可能由于无意修改了数据而导致程序出现非常严重的故障。

下面来测试该栈。程序清单 10.12 模拟了售货员的行为——使用栈的后进先出方式,从购物筐的最上面开始处理购物订单。

程序清单 10.12 stacker.cpp

程序清单 10.12 中的 while 循环删除输入行中剩余部分,就现在而言这并非是必不可少的,但它使程序的修改更方便(第 14 章将对这个程序进行修改)。下面是该程序的运行情况:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文