面向对象程序设计语言课件

上传人:我*** 文档编号:144267084 上传时间:2020-09-07 格式:PPT 页数:34 大小:336KB
返回 下载 相关 举报
面向对象程序设计语言课件_第1页
第1页 / 共34页
面向对象程序设计语言课件_第2页
第2页 / 共34页
面向对象程序设计语言课件_第3页
第3页 / 共34页
面向对象程序设计语言课件_第4页
第4页 / 共34页
面向对象程序设计语言课件_第5页
第5页 / 共34页
点击查看更多>>
资源描述

《面向对象程序设计语言课件》由会员分享,可在线阅读,更多相关《面向对象程序设计语言课件(34页珍藏版)》请在金锄头文库上搜索。

1、1,面向对象程序设计语言C+,电子科技大学计算机学院,2,第九章 模板,9.1 类属的概念 类属(genericity)首先由 ALGOL 68 引入,是 Ada 语言的典型成分。 类属的最重要的形式,类型参数化; 它表现了使用一个或多个类型去参数化一个软件元素的能力。 类属又可分为无约束类属机制和约束类属机制,其中无约束类属机制是指对类属参数没有施加任何特殊的要求,而约束类属机制则意味着类属参数需要一定的辅助条件。,3,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 考虑一个函数,它用来交换两个变量的值。使用非静态强类型语言,可编写出如下函数(用类 Ada 的语法形式): pro

2、cedure swap(x,y) is t : local; begin t := x; x := y; y := t; end swap; 这里,被交换的元素 x 和 y 的类型以及局部变量 t 的类型都不需要指定,这显得很自由,可能会导致错误。如果 a 是整型变量,b 是字符串,swap(a,b)显然引起错误,而编译程序却无法检查。,4,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 考虑一个函数,它用来交换两个变量的值。使用非静态强类型语言,可编写出如下函数(用类 Ada 的语法形式): procedure swap(x,y) is t : local; begin t :=

3、 x; x := y; y := t; end swap; 这里,被交换的元素 x 和 y 的类型以及局部变量 t 的类型都不需要指定,这显得很自由,可能会导致错误。如果 a 是整型变量,b 是字符串,swap(a,b)显然引起错误,而编译程序却无法检查。,5,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 为了解决这一问题,像Pascal这样的静态强类型语言需要程序员明确地定义所有变量和形参的类型。迫使函数调用时进行实参与形参之间的强类型检查,以避免产生类型不兼容的错误。这就产生了不愉快的后果,在缺少重载机制支持的情况下,要为每种类型的交换操作声明一个新的过程:int_swap,

4、str_swap, float_swap,。,6,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 相比之下,含类属机制的这类语言提供了一种折衷的办法,它既不像非类型语言那样太多的自由,也不像Pascal那样的强类型语言施加太多的约束。一个类属化的swap可以用类 Ada 语言声明为 generic type T is private; procedure swap(x,y: in out T) is t : T;5 begin t:=x; x:=y; y:=t; end swap;,7,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 语句 generic 引入了一个类型

5、参数T,也称类属参数T,swap的两个形参x、y和局部变量t都具有T的类型,这样,只要类属参数T实例化为某一具体类型,例如integer类型或者string类型,swap函数都能正确工作。 swap表示一个函数模板,或称类属函数,它代表的是一类函数实际的函数是将T实例化而获得的。 procedure int_swap is new swap (integer); procedure str_swap is new swap (string);,8,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 语句 generic 引入了一个类型参数T,也称类属参数T,swap的两个形参x、y和局

6、部变量t都具有T的类型,这样,只要类属参数T实例化为某一具体类型,例如integer类型或者string类型,swap函数都能正确工作。 swap表示一个函数模板,或称类属函数,它代表的是一类函数实际的函数是将T实例化而获得的。 procedure int_swap is new swap (integer); procedure str_swap is new swap (string);,9,第九章 模板,9.1 类属的概念 9.1.1无约束类属机制 这种类属机制可以称为无约束类属机制,所谓无约束是指,对于作为类属的参数,没有施加任何特殊的条件,这里,我们可以交换任意类型的变量。,10,第

7、九章 模板,9.1 类属的概念 9.1.2约束类属机制 考虑下面的例子,假定我们需要一个类属函数来计算两个值的最小值。其类属程序如下: generic type T is private; function minimum (x,y:T) return T is begin if x = y then return x; else return y endif; end minimum,11,第九章 模板,9.1 类属的概念 9.1.2约束类属机制 在这个函数声明中,比较运算符“=”因类型 T 不同,它的意义是很不相同的。显然,结构变量的比较与整型变量的比较有很大的差别。类型T中必须定义比较运

8、算符“=”,这个函数声明才有意义。关于这一特性的检查只有在允许时才能进行。因此,我们需要按某种方式来指明在类型T中必须具备有关的操作。,12,第九章 模板,9.1 类属的概念 9.1.2约束类属机制 在这个函数声明中,比较运算符“=”因类型 T 不同,它的意义是很不相同的。显然,结构变量的比较与整型变量的比较有很大的差别。类型T中必须定义比较运算符“=”,这个函数声明才有意义。关于这一特性的检查只有在允许时才能进行。因此,我们需要按某种方式来指明在类型T中必须具备有关的操作。 在 Ada 中,采用如下方式解决这一问题,即把运算符“=”作为类属程序单元自身的类属参数来对待。,13,第九章 模板,

9、9.1 类属的概念 9.1.2约束类属机制 generic type T is private; with function ; function minimum (x,y:T) return T is begin if x = y then return x; else return y endif; end minimum,14,第九章 模板,9.1 类属的概念 9.1.2约束类属机制 其中,关键词 with 引入函数的类属参数,这里是“=”。因此,对任意类型 T,我们可以定义 minimum 的一个实例,但还需要提供类属参数“=”的实例(这里视为“=”的实例函数),假定“=”的实例函数为

10、 T_le (例如 integer_le)。这样,实际函数的声明为 function T_minimum is new minimum (integer,integer_le),15,第九章 模板,9.1 类属的概念 9.1.2约束类属机制 可见,类属函数minimum实例化为一实际函数时,需要两个类属实参:integer和integer_le,其中integer_le是integer的约束条件。这种形式的类属机制称为约束类属机制,作为类属实参的类型integer,必须具备integer_le的条件。,16,第九章 模板,9.2 模板的概念 C+ 语言也具有类属机制,它被称为模板。 借助于C+

11、中运算符重载等功能,模板实现了无约束类属机制和约束类属机制。 C+模板允许用户构造类属函数和类属类,也称为模板函数和模板类。,17,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 利用函数max求两个值中的最大者。 一般的解决办法就是写一系列的函数,来分别完成整型、浮点型和用户自定义类型的求解。 所有这些函数(的代码)几乎都是一模一样的,只是操作的类型不同。,int max(int x,int y) return (x y) ? x : y; long max(double x,double y) return (x y) ? x : y; ,19,第九章 模板,9.2 模板的

12、概念 9.2.1函数模板与模板函数 一个变通的方法是使用宏定义: #define max(x, y) (x) (y) ? (x) : (y) 这样做虽然解决了代码维护问题,但由于宏定义避开了类型检查机制,从而可能带来一些不易发觉的错误。例如,使用宏可能会导致在一个 int 参数和一个 struct 参数之间进行比较。,20,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 另一种解决办法是使用模板。如果使用模板,数据类型本身就是一个参数 template T max(T x,T y) return (xy) ? x : y; 其中,typename关键字可以替换为class。,2

13、1,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 这样定义的max代表的是一类函数,如果要这个max函数真正进行求最大值的操作,首先必须将模板参数T实例化,从这个意义上说,这里定义的max函数并不是一个完全的函数。 我们称它为函数模板。因此,函数模板代表了一类函数,而且它不是一个完全的函数,必须将其模板参数T实例化后,才能完成具体函数的功能。,22,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 将T实例化的参数常常称为模板实参。用模板实参实例化的函数称为模板函数,例如: void func( ) int i1,i2; double d1,d2; int in

14、um=max(i1,i2); double dnum=max(d1,d2); ,int max(int x,int y) return (x y) ? x : y; long max(double x,double y) return (x y) ? x : y; void func( ) int i1,i2; double d1,d2; int inum=max(i1,i2); double dnum=max(d1,d2); ,24,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 这里生成了两个模板函数。,25,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数

15、2.重载模板函数 有些特殊情况需要函数模板参与重载,C+允许函数模板被一个或多个同名的非模板函数重载。考虑下面的例子: void fun(int num, char cha) max(num, num ); max(cha, cha); max(num, cha); / 错误,max(int, char) 无法匹配 max(cha, num); / 错误,max(int, char) 无法匹配 ,26,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 这里出现了错误。问题在于模板类型并不知道int和char之间能进行隐式类型转换。但是,这样的转换在C+中是很普遍的。 为了解决这个

16、问题,C+允许一个函数模板可以使用多个模板参数或者重载一个函数模板。 template T max(T a, D b) return (ab)? a : b; ,27,第九章 模板,9.2 模板的概念 9.2.1函数模板与模板函数 template T max(T a, T b) return (ab) ? a : b; int max(int, int); / 显式地声明 max(int,int) / 这是一个重载的非模板函数,28,第九章 模板,9.2 模板的概念 9.2.2类模板与模板类 请大家考虑一个向量类。可以发现,在没有引入模板类的概念之前,为了让向量适应不同的类型,我们不得不写一系列的类,诸如整型向量类、浮点向量类以及类类型向量类。而这些类除了操作的类型不同外,其它的部分都几乎一模一样。这对我们管理源代码带来极大的麻烦。 类模板机制比较完美地解决了这个问题。让我们来看看例子:,29,第九章 模板,9.2 模板的概念 9.2.2

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 办公文档 > PPT模板库 > PPT素材/模板

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号