面向对象程序的设计语言C++ppt课件_第1页
面向对象程序的设计语言C++ppt课件_第2页
面向对象程序的设计语言C++ppt课件_第3页
面向对象程序的设计语言C++ppt课件_第4页
面向对象程序的设计语言C++ppt课件_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1第九章 模板 9.1 类属的概念 类属genericity首先由 ALGOL 68 引入,是 Ada 言语的典型成分。 类属的最重要的方式,类型参数化; 它表现了运用一个或多个类型去参数化一个软件元素的才干。 类属又可分为无约束类属机制和约束类属机制,其中无约束类属机制是指对类属参数没有施加任何特殊的要求,而约束类属机制那么意味着类属参数需求一定的辅助条件。2第九章 模板 9.1 类属的概念 9.1.1无约束类属机制 思索一个函数,它用来交换两个变量的值。运用非静态强类型言语,可编写出如下函数用类 Ada 的语法方式: procedure swap(x,y) is t : local; be

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

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

4、 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;6第九章 模板 9.1 类属的概念 9.1.1无约束类属机制 语句 generic 引入了一个类型参数T,也称类属参数T,swap的两个形参x、y和部分变量t都具有T的类型,这样,只需

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

6、者string类型,swap函数都能正确任务。 swap表示一个函数模板,或称类属函数,它代表的是一类函数实践的函数是将T实例化而获得的。 procedure int_swap is new swap (integer); procedure str_swap is new swap (string);8第九章 模板 9.1 类属的概念 9.1.1无约束类属机制 这种类属机制可以称为无约束类属机制,所谓无约束是指,对于作为类属的参数,没有施加任何特殊的条件,这里,我们可以交换恣意类型的变量。9第九章 模板 9.1 类属的概念 9.1.2约束类属机制 思索下面的例子,假定我们需求一个类属函数来计

7、算两个值的最小值。其类属程序如下: 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 minimum10第九章 模板 9.1 类属的概念 9.1.2约束类属机制 在这个函数声明中,比较运算符“=因类型 T 不同,它的意义是很不一样的。显然,构造变量的比较与整型变量的比较有很大的差别。类型T中必需定义比较运算符“=,这个函数声明才有意义。关于这一特性的检查只需在允许时才干进展。因此,我们需求按某种方式来指明在类

8、型T中必需具备有关的操作。11第九章 模板 9.1 类属的概念 9.1.2约束类属机制 在这个函数声明中,比较运算符“=因类型 T 不同,它的意义是很不一样的。显然,构造变量的比较与整型变量的比较有很大的差别。类型T中必需定义比较运算符“=,这个函数声明才有意义。关于这一特性的检查只需在允许时才干进展。因此,我们需求按某种方式来指明在类型T中必需具备有关的操作。 在 Ada 中,采用如下方式处理这一问题,即把运算符“=作为类属程序单元本身的类属参数来对待。12第九章 模板 9.1 类属的概念 9.1.2约束类属机制 generic type T is private; with functio

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

10、(x y) ? x : y; 第九章 模板 9.2 模板的概念 9.2.1函数模板与模板函数 一个变通的方法是运用宏定义: #define max(x, y) (x) (y) ? (x) : (y) 这样做虽然处理了代码维护问题,但由于宏定义避开了类型检查机制,从而能够带来一些不易觉察的错误。例如,运用宏能够会导致在一个 int 参数和一个 struct 参数之间进展比较。19第九章 模板 9.2 模板的概念 9.2.1函数模板与模板函数 另一种处理方法是运用模板。假设运用模板,数据类型本身就是一个参数 template T max(T x,T y) return (xy) ? x : y;

11、其中,typename关键字可以交换为class。20第九章 模板9.2 模板的概念9.2.1函数模板与模板函数 这样定义的max代表的是一类函数,假设要这个max函数真正进展求最大值的操作,首先必需将模板参数T实例化,从这个意义上说,这里定义的max函数并不是一个完全的函数。 我们称它为函数模板。因此,函数模板代表了一类函数,而且它不是一个完全的函数,必需将其模板参数T实例化后,才干完成详细函数的功能。 21第九章 模板 9.2 模板的概念 9.2.1函数模板与模板函数 将T实例化的参数经常称为模板实参。用模板实参实例化的函数称为模板函数,例如: void func( ) int i1,i2

12、; double d1,d2; int inum=max(i1,i2); double dnum=max(d1,d2); 22int 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); 第九章 模板 9.2 模板的概念 9.2.1函数模板与模板函数 这里生成了两个模板函数。 24第九章 模板 9.2 模板的

13、概念 9.2.1函数模板与模板函数 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) 无法匹配 25第九章 模板 9.2 模板的概念 9.2.1函数模板与模板函数 这里出现了错误。问题在于模板类型并不知道int和char之间能进展隐式类型转换。但是,这样的转换在

14、C+中是很普遍的。 为理处理这个问题,C+允许一个函数模板可以运用多个模板参数或者重载一个函数模板。 template T max(T a, D b) return (ab)? a : b; 26第九章 模板 9.2 模板的概念 9.2.1函数模板与模板函数 template T max(T a, T b) return (ab) ? a : b; int max(int, int); / 显式地声明 max(int,int) / 这是一个重载的非模板函数27第九章 模板 9.2 模板的概念 9.2.2类模板与模板类 请大家思索一个向量类。可以发现,在没有引入模板类的概念之前,为了让向量顺应不

15、同的类型,我们不得不写一系列的类,诸如整型向量类、浮点向量类以及类类型向量类。而这些类除了操作的类型不同外,其它的部分都几乎一模一样。这对我们管理源代码带来极大的费事。 类模板机制比较完美地处理了这个问题。让我们来看看例子:28第九章 模板 9.2 模板的概念 9.2.2类模板与模板类 template class vector T * data; int size; public: vector(int s) size = s; data = new Tsize ;vector() delete data; T & operator (int num) return datenum;

16、 ;29第九章 模板 9.2 模板的概念 9.2.2类模板与模板类 这时,类vector声明了一个数组类,当T被实例化为int、char、float、string或complex甚至恣意类类型Myclass时,vector被实例化为整型数组、字符数组、浮点数数组、串数组或复数的数组甚至恣意类类型Myclass的数组。从这个意义上说,vector是一个不完全的类。这时vector被称为类模板,vector是该类模板的名字。30第九章 模板 9.2 模板的概念 9.2.2类模板与模板类 将模板参数实例化的参数常称为模板实参,例如,int、char等等。用模板实参生成的类称为模板类。例如vector是一个模板类: vector vec(5); / 产生一个整型向量31第九章 模板 9.2 模板的概念 9.2.2类模板与模板类 上述例子都只运用了一个模板参数,实践上允许运用多个参数。模板参数可以是类型,也可以是非类型的数据,例如: template class buffer . ;32第九章 模板 9.2 模板的概念 9.2.3模板的特化 他可以用模板实参来

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论