面向对象泛型技术_第1页
面向对象泛型技术_第2页
面向对象泛型技术_第3页
面向对象泛型技术_第4页
面向对象泛型技术_第5页
已阅读5页,还剩64页未读 继续免费阅读

下载本文档

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

文档简介

面向对象设计方法9.1泛型简介9.2C++中的泛型9.3STL9.4JAVA中的泛型9.5C++和JAVA中泛型的比较9.6泛型的好处第九章泛型技术1.泛型泛型(Generic),是指具有在多种数据类型上皆可操作的含意。既编写的代码可以在不同的数据类型上重用。实现对源代码进行重用,既不是通过继承和聚合重用对象代码,也不是代码的复制粘贴复用。泛型编程(GenericProgramming)

9.1泛型简介9.2.1C++中泛型简介在C++语言中称泛型为模板(template),模板由函数模板和类模板两部分组成,以所处理的数据类型的说明作为参数的函数叫做函数模板,而以所处理的数据类型的说明作为参数的类就叫类模板。9.2C++中的泛型1.示例:加法函数的重载intAdd(inta,intb){ returna+b;}longAdd(longa,longb){ returna+b;}根据不同的数据类型进行多次重载,但是实现的代码都是一致的。9.2.2函数模板2.函数模板的语法template<classType>TypeAdd(Typea,Typeb){ returna+b;}

具体使用为:Add(10,100);Add(10.1,23.4);9.2.2函数模板template:

关键字,总是放在模板的定义与声明的最前面<>:模板参数列表,如果有多个模板参数用逗号隔开;模板参数分模板类型参数和模板非类型参数(代表一个常量表达式)。class:关键字,声明模板类型参数,用typename替代也可以。9.2.2函数模板template<classType>例如:template<classType,classTypeB>TypeAdd(Typea,TypeBb){ returna+b;}

注意此时a和b是两种不同的变量类型9.2.2函数模板例如:template<classType,intsize>TypeAdd(Typea){ returna+size;}

注意此时a是模板类型参数,而size是模板非类型参数。模板非类型参数是常整数(包括枚举值)或者指向外部链接对象的指针,不能是浮点数和类对象。9.2.2函数模板例如:template<classType>TypeAdd(Typea,intsize){ returna+size;}

注意此时a是模板类型参数,而size是函数参数9.2.2函数模板3.模板函数的实例化用系统实际的内置或用户定义类型将替换模板的类型参数。具体见源代码示例。注意:不论是内置类型还是用户自定义类型必须要支持模板函数内的操作。9.2.2函数模板1.示例:List链表的实现classListInt{public: voidAdd(intnValue); boolInsert(intnIndex,intnValue); intRemove(intnIndex);};只能满足整型链表的要求,要根据不同的数据类型编写多个链表类。9.2.3类模板2.类模板的定义template<classT>classList{public: voidAdd(TnValue); boolInsert(intnIndex,TnValue); TRemove(intnIndex);};9.2.3类模板3.类模板方法的实现方式template<classT>voidList<T>::Add(TnValue){…….}

9.2.3类模板4.类模板的实例化用系统实际的内置或用户定义类型将替换模板的类型参数。List<int>intList;List<double>douList;注意:不论是内置类型还是用户自定义类型必须要支持类模板内的操作。

9.2.3类模板9.3.1STL简介1.STL的含义

STL:StandardTemplateLibrary,标准模板库,STL是泛型编程的实现品;STL就是一个数据结构和算法框架。

STL的设计目标就是将不同的算法和数据结构结合起来,并获得最佳效率。9.3STL2.STL与C++标准程序库

STL于1994年被纳入C++标准程序库。STL虽然加入C++标准库的时间相对较晚,但它却是C++标准程序库中最具革命性的部分,同时也是C++标准程序库中最重要的组成部分。9.3.1STL简介3.STL内容

STL的代码从广义上讲分为三类:container(容器)、algorithm(算法)和iterator(迭代器),几乎所有的代码都采用了模板类和模板函数的方式。9.3.1STL简介容器对最常用的数据结构提供了支持:vector,list,set,map,stack和queue。遗憾的是标准中没有支持哈希表。9.3.1STL简介算法STL提供了大约100个实现算法的模版函数。其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。9.3.1STL简介迭代器

迭代器在STL中用来将算法和容器联系起来,起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的,每一个容器都定义了其本身所专有的迭代器,用以存取容器中的元素。9.3.1STL简介1.命名空间(namespace)std当你采用不同的模块和程序库时,经常会出现名称冲突现象,这是因为不同的模块和程序库可能针对不同的对象使用相同的标识符.namespace可以解决该问题。

C++标准程序库中所以的标识符都统一到std这个命名空间。9.3.2几个基本概念使用c++标准程序库的标识符有三种方法可供选择:1>直接指定标识符使用std::cout<<std::hex<<3.4<<std::endl;反是使用了C++标准程序库的标识符的地方均在关键字前增加“std::”。9.3.2几个基本概念2>使用usingdeclaration,在文件头处申明如下:usingstd::cout;usingstd::endl;cout<<std::hex<<3.4<<endl;只有在文件头声明了using语句的标识符,在使用该标识符,不需要添加“std::”。9.3.2几个基本概念2>使用usingdeclaration,在文件头处申明如下:usingstd::cout;usingstd::endl;cout<<std::hex<<3.4<<endl;只有在文件头声明了using语句的标识符,在使用该标识符,不需要添加“std::”。9.3.2几个基本概念3>使用usingdirective,在文件头处申明如下:usingnamespacestd;cout<<hex<<3.4<<endl;这种使用方式最简单,所有在使用该标识符,都不需要添加“std::”,但在大程序中可能会出现命名冲突。9.3.2几个基本概念2.头文件

C++标准程序库中头文件没有扩展名,使用如下:

#include<iostream>#include<string>为了向下兼容,你也可以使用旧式的C++头文件:#include<stdlib.h>9.3.2几个基本概念3.配置器(Allocators)配置器用于处理内存配置和寻址,是一种特定的内存模型。9.3.2几个基本概念1.容器的分类9.3.3STL容器序列式容器每个元素均有固定的位置---取决于插入的时机和地点,和元素值无关。STL提供了vector、list和deque三个序列式容器。关联式容器元素位置取决于特定的排序准则和元素值,和插入次序无关。STL提供了四个关联式容器:set、multiset、map和multimap。9.3.3STL容器2.

vectorVector将其元素置于一个动态数组中加以管理:它允许随机存取,也就是说你可以利用索引直接存取任何一个元素。在数组尾部增加元素或移除元素均非常快速,但是在中部或头部安插元素就比较费事。(见示例)9.3.3STL容器3.

dequedeque:double-endedqueue,双端队列。它也是一个动态数组,但是可以向两端发展,因此无论先头部还是尾部安插元素都是非常迅速。但如果在中间插入数据比较费事,因为要移动其他元素。(见示例)9.3.3STL容器4.

listlist,双向链表,每个元素都有其前趋元素和后继元素。List不提供随机存取,但是其在任何位置插入或删除元素速度快,效率高。(见示例)9.3.3STL容器5.

setset的内部元素依据其值自动排序,每个元素值只能出现一次,不允许重复。6.Multiset

和set相同,只不过它允许重复元素。7.Mapmap的元素都是“实值/键值”所形成的一个对组,每个元素有一个键,是排序的基础。8.Multimap

和map相同,只是允许重复键值。9.3.3STL容器1.

STL容器的共同能力

1>所有容器提供的都是“Value语意”而非“reference语意”。也就是说容器进行元素安插操作时,内部实施的是拷贝操作,置于容器内。因此STL容器的每一个元素都必须能够被拷贝。------拷贝构造函数。

2>每个容器都有迭代器,利用迭代器就可以遍历容器里的每个元素。

9.3.4容器的共同能力和操作

3>一般而言,各项操作并非绝对安全。调用者必须确保传给操作函数的参数符合需求。违反这些需求(例如使用非法索引)会导致未定义的行为。

9.3.4容器的共同能力和操作2.

STL容器的共同操作初始化与大小相关的函数比较赋值9.3.4容器的共同能力和操作提供容器默认初始化的构造函数。通常每个容器都有几个不同的构造函数,提供容器不同的初始化方法将容器初始化为现有同类容器副本的构造函数撤消容器时,进行内存处理判容器是否为空,空返回true,不空返回false返回容器中最多允许的元素量返回容器当前元素量默认构造函数拷贝构造函数析构函数empty()max_size()size()说明标准库容器共有的函数将一个容器赋值拷贝给另一个同类容器交换两个容器的元素如果前面的容器小于后面的容器,则返回true,否则返回false,不适用于priority_queue如果前面的容器小于等于后面的容器,则返回true,否则返回false,不适用于priority_queue如果前面的容器大于后面的容器,则返回true,否则返回false,不适用于priority_queue如果前面的容器大于等于后面的容器,则返回true,否则返回false,不适用于priority_queue如果前面的容器等于后面的容器,则返回true,否则返回false,不适用于priority_queue如果前面的容器不等于后面的容器,则返回true,否则返回false,不适用于priority_queueoperator=swap()operator<operator<=operator>operator>=operator==operator!=说明标准库容器共有的函数获得指向被控序列开始处的迭代子,引用容器第一个元素获得指向被控序列末端的迭代子,引用容器最后一个元素的后继位置获得指向被控序列末端的反转型迭代子,引用容器最后一个元素。实际上这是该容器前后反转之后的begin()获得指向被控序列开始处的反转型迭代子,引用容器第一个元素的前导位置。实际上这是该容器前后反转之后的end()从容器中清除一个或几个元素从容器中清除所有元素begin()end()rbegin()rend()erase()clear()说明只在第一类容器中的函数vector容器要求其元素必须有可赋值和可拷贝属性。1.大小和容量2.操作函数3.作为普通数组使用4.异常处理5.实例分析(见源代码)9.3.5Vector

迭代器是一个可以遍历STL容器内全部或部分元素的对象。支持*、++、==、!=、->、=操作符。见示例9.3.6迭代器STL提供了一些标准算法,包括搜寻、排序、拷贝、重新排序、修改、数值运算等十分基本而普遍的算法。算法并非容器类型的成员函数,而是一种搭配迭代器使用的全局函数。见示例。

9.3.7算法

算法分类变化序列算法copy,remove,fill,replace,random_shuffle,swap,会改变容器非变化序列算法:adjacent-find,equal,mismatch,find,count,search,count_if,for_each,search_n以上函数模板都在<algorithm>中定义此外还有其他算法,比如<numeric>中的算法算法示例:find()template<classInIt,classT>InItfind(InItfirst,InItlast,constT&val);

first和last这两个参数都是容器的迭代器,它们给出了容器中的查找区间起点和终点。这个区间是个左闭右开的区间,即区间的起点是位于查找范围之中的,而终点不是算法示例:find()val参数是要查找的元素的值函数返回值是一个迭代器。如果找到,则该迭代器指向被找到的元素。如果找不到,则该迭代器指向查找区间终点。#include<vector>#include<algorithm>#include<iostream>usingnamespacestd;main(){ intarray[10]={10,20,30,40}; vector<int>v; v.push_back(1); v.push_back(2); v.push_back(3); v.push_back(4); vector<int>::iteratorp; p=find(v.begin(),v.end(),3); if(p!=v.end()) cout<<*p<<endl; p=find(v.begin(),v.end(),9); if(p==v.end()) cout<<"notfound"<<endl; p=find(v.begin()+1,v.end()-2,1); if(p!=v.end()) cout<<*p<<endl; int*pp=find(array,array+4,20); cout<<*pp<<endl;}输出:3notfound320

帮助程序员防止“被异常抛出时发生资源泄露”。voidf(){ClassA*ptr=newClassA();try{...}catch(...){throw;}deleteptr;}

9.3.8智能指针有错误?正确为voidf(){ClassA*ptr=newClassA;try{...}catch(...){

deleteptr;throw;}deleteptr;}

9.3.8智能指针使用智能指针#include<memory>voidf(){std::auto_ptr<ClassA>ptr(newClassA);...}9.3.8智能指针智能指针的使用方法std::auto_ptr<ClassA>ptr1(newClassA);//OKstd::auto_ptr<ClassA>ptr2=newClassA;//ERROR9.3.8智能指针可以当着是一种特殊的vector容器。9.3.9string(字符串)使用STL技术修改main()函数中的代码,使之成为异常安全的ClassDerived{public:voidOnOpen(){//这里可能抛出异常}}9.3.10一道关于STL的面试题intmain(){Derived*pBase=NULL;pBase=newDerived();if(pBase!=NULL){pBase->OnOpen();deletepBase;}return0;}9.3.10一道关于STL的面试题解决方法std::auto_ptr<Derived>pBase(newDerived());pBase->OnOpen();

9.3.10一道关于STL的面试题STL仅仅是一个标准,有很多公司实现了这个标准,各具特点。

STLport是一个跨平台可移植版本,应用比较广泛。

/

9.3.11STL选择C++标准程序库自修教程与参考手册泛型编程与STLSTL源码剖析EffectiveSTL(STL高效编程)C++设计新思维9.3.12C++泛型书籍推荐1.JDK1.4和JDK1.5部分函数比较类ArrayList

接口Comparable9.4JAVA中的泛型2.泛型方法和泛型类的声明publicclassPair<T>

publicclassPair<T,U>{...}public<T>TgetMiddle(T[]a)9.4JAVA中的泛型3.类型变量的限定有时候类和方法需要类型变量进行一定的限制。例如:9.4JAVA中的泛型classArrayAlg{publicstatic<T>Tmin(T[]a){if(a==null||a.length==0)returnnull;Tsmallest=a[0];for(inti=1;i<a.l

温馨提示

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

评论

0/150

提交评论