设为首页 加入收藏

TOP

2.1 类型无关的数据结构
2013-10-07 16:30:50 来源: 作者: 【 】 浏览:200
Tags:2.1 类型 无关 数据结构

第2章 类亦模板

概述

学习软件开发的朋友,一定听说过这句名言:数据结构+算法=程序(Niklaus E. Wirth)。通过第1章的讨论我们知道,借助函数模板,算法描述可以脱于具体类型之外。借助C++(www.cppentry.com)语言中的另一大模板功能——类模板,数据结构的描述同样也可以脱于数据类型之外,而只专注于数据存取方法及数据间的关联方式。

2.1 类型无关的数据结构

以最常见的栈(stack)为例,栈是一种先入后出队列,其所存数据总数不定,一般可由链表来实现。由于栈只可在栈首存取数据,无需对链表中间数据进行操作,所以最简单的实现方式是单向链表。

单向链表由一系列的节点构成。节点包含两个数据,一个是该节点所存数据,另一个是一个指向链表中下一节点的指针。可见,抽象的数据结构描述也可以与具体的类型无关。但在C++(www.cppentry.com)中,如果没有模板,则会因具体类型不同而不得不将数据结构一一实现。例如同样是链表节点,如果一个要保存整数值而另一个要保存浮点数值,则其节点类分别写成以下形式:

  1. struct int_node  
  2. {  
  3.     int value;  
  4.     int_node *next;  
  5. };  
  6.  
  7. struct float_node  
  8. {  
  9.     float value;  
  10.     float_node *next;  
  11. }; 

显然,两个节点类很类似,都有两个成员变量分别名为value和next,并且next是一个指针。只因所存数据不同而使其成员变量类型不同而已。

我们已经领略过函数模板为我们展开的与类型无关的算法描述图景。现在,类模板将为我们展开另一幅图景——与类型无关的数据结构。例如以上的节点类可以统一用类模板表示,如例2.1所示。

例2.1

  1. template <typename T=int> 
  2. struct list_node  
  3. {  
  4.     T value;  
  5.     list_node *next;  
  6. }; 

与函数模板相同,类模板也是以关键字template开头,后接模板参数以及类模板的声明或者实现。模板参数在整个类实现中都可见,也就是可以在类实现中利用模板参数定义成员变量类型、成员函数参数类型及返回值类型等。在本例中,模板参数T被用于定义成员变量value的类型,即节点所要保存的数据类型。而另一个成员变量next是一个指向list_node的指针,但list_node只是一个模板名,并不代表实际的类,这似乎有点儿说不通。在此,C++(www.cppentry.com)有一个特别的规定:在一个类模板内出现的自身模板名,等价于该模板被调用时所生成的实例。此处的list_node等价于list_node<T>,所以next指针是一个指向同类的指针。

调用类模板生成实例的方法与调用函数模板相同,采用类模板名后接尖括号内的模板实参列表的形式。例如如下代码。

  1. list_node<int>inode;  // 保存整数值的节点。等价于int_node  
  2. list_node<float>fnode;  // 保存字符值的节点。等价于float_node 

在介绍函数模板时曾经提过,新的C++(www.cppentry.com)11标准开始支持函数模板参数默认值,而在前一版标准C++(www.cppentry.com)98中就已经允许为类模板参数赋默认值了,其用法如例2.1中的模板参数列表中一样,即在模板参数名之后用“=”后接默认值。

如果类模板参数有默认值,则在实参列表中可将其省略。如果所有参数都有默认值,则模板实参列表可以省略,但尖括号不能省,如以下代码所示:

  1. list_node<>inode;   // 保存整数值的节点。利用模板参数默认值 

与函数模板不同的是,类模板没有模板参数实参推导机制(使用类时不需要参数,自然也就无法根据参数推导出模板参数了)。所以,对于没有默认值的模板参数,只能为其一一赋值,而可以省略的仅限于列表最后有默认值的若干相邻参数。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇1.4.1 什么是外名模板 下一篇2.2.1 栈类模板实例

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: