面向对象程序设计(C)_第1页
面向对象程序设计(C)_第2页
面向对象程序设计(C)_第3页
面向对象程序设计(C)_第4页
面向对象程序设计(C)_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

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

文档简介

1、第第12章章 模板模板(Template)面向对象程序设计面向对象程序设计(C+)面向对象程序设计 中国科学技术大学计算机系 马建辉212.1 引言引言面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉312.1 引言:引言:IntStackF 创建一个栈,这个栈类只存放创建一个栈,这个栈类只存放intint类型的值类型的值1. 1. 支持初始化、支持初始化、push()push()、pop()pop()、清除等方法;、清除等方法;2. 2. 栈中所有元素的类型都是栈中所有元素的类型都是.面向对象程序设计面向对象程序设计 中国科学技术

2、大学计算机系中国科学技术大学计算机系 马建辉马建辉4VP用来存放用来存放intint的栈类的栈类 IntStackIntStackclass IntStack int *v; / 栈底栈底 int *p; / 栈顶栈顶 int sz; / 栈的大小栈的大小public: IntStack(int s) v=p=new intsz=s; IntStack() delete v; void push(int a) *p+ = a; int pop() return * - p ; int size() const return p-v; ; 面向对象程序设计 中国科学技术大学计算机系 马建辉512

3、.2 代码重用代码重用面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉612.2 如何实现代码重用?如何实现代码重用?VPVPCharStackObjStack 现在希望再创建能存现在希望再创建能存放其他类型的栈类,如:放其他类型的栈类,如:char, float,char, float, 甚至用户甚至用户自定义的类型对象。自定义的类型对象。 从栈的结构和操作方从栈的结构和操作方式上来说,除了每个元素式上来说,除了每个元素的类型不一样外,其它没的类型不一样外,其它没有任何区别。因此应该可有任何区别。因此应该可以重用以重用IntStackIntSt

4、ack的代码。的代码。面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉7问题是:如何重用?问题是:如何重用?面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉812.2.1 C的方法之一:代码拷贝的方法之一:代码拷贝class CharStack char *v; / 栈底栈底 char *p; / 栈顶栈顶 int sz; / 栈的大小栈的大小public: CharStack(int s) v=p=new charsz=s; CharStack() delete v; void push(char

5、 a) *p+ = a; char pop() return * - p ; int size() const return p-v; ;缺点:缺点:1. 1. 表现繁琐表现繁琐; ;2. 2. 易发生错误易发生错误; ;3. 3. 缺乏美感缺乏美感; ;非常低效!非常低效!面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉912.2.2 C的方法之二:的方法之二:typedeftypedef int T;class Stack T *v; / 栈底栈底 T *p; / 栈顶栈顶 int sz; / 栈的大小栈的大小public: Stack(in

6、t s) v=p=new Tsz=s; Stack() delete v; void push(T a) *p+ = a; T pop() return * - p ; int size() const return p-v; ;缺点:缺点:1. 1. 每次使用每次使用StackStack之前,都必之前,都必 须加上须加上typedeftypedef语句,很麻语句,很麻 烦。烦。2. 2. 由于由于T T是全局名,无法重新是全局名,无法重新 定义,一个类不能同时用到定义,一个类不能同时用到 char char栈和栈和intint栈;栈;面向对象程序设计面向对象程序设计 中国科学技术大学计算机系

7、中国科学技术大学计算机系 马建辉马建辉1012.2.3 smalltak方法方法(略略)使用继承使用继承 复杂复杂, ,混乱混乱! !面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉1112.2.4 C+的方法:模板的方法:模板 改进改进typedef,将它从预处理器移入到编译器中。,将它从预处理器移入到编译器中。新的代码替换装置称为新的代码替换装置称为“模板模板”(template)。 非常象宏,却更清晰,更易于使用;非常象宏,却更清晰,更易于使用; 模板实际上是一组类;模板实际上是一组类; 形式上很简洁。形式上很简洁。面向对象程序设计 中国科

8、学技术大学计算机系 马建辉1212.3 模板语法模板语法面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉1312.3.1 类模板定义类模板定义template class 类模板名类模板名 / 类模板的定义类模板的定义;注:注:T T是一个类模板的类型参数,可以有一个或是一个类模板的类型参数,可以有一个或多个,可以是任意类型。多个,可以是任意类型。面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉14template class Stack T *v; / 栈底栈底 T *p; / 栈顶栈顶 int

9、sz; / 栈的大小栈的大小public: Stack(int s) v=p=new Tsz=s; Stack() delete v; void push(T a) *p+ = a; T pop() return * - p ; int size() const return p-v; ;例:例:Stack面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉1512.3.2 类模板实例化类模板实例化 给类模板的参数指定具体的类型,这一过程称为给类模板的参数指定具体的类型,这一过程称为 “ “类模板的实例化类模板的实例化”。类模板名 Stack; /

10、实例化成实例化成 int 型栈类;型栈类; Stack; / 实例化成实例化成 char 型栈类;型栈类;注意:类模板实例化后的结果是类,而不是对象!注意:类模板实例化后的结果是类,而不是对象!面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉1612.3.3 类对象生成类对象生成 类模板实例化得到的类可以进行实例化,生成最类模板实例化得到的类可以进行实例化,生成最 终的对象。终的对象。Stack si(20) ; / 创建一个大小为创建一个大小为20的整形栈;的整形栈;Stack si(40); / 创建一个字符型栈;创建一个字符型栈;Stack

11、 stack(100); / error, 未指定模板参数,未指定模板参数, 面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉17类模板与类的实例化类模板与类的实例化StackStack Stack Stack sint(10) Stack si2(20) 模板实例化模板实例化类实例化类实例化面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉18完整的完整的stack程序:程序:template class Stack T *v; / 栈底栈底 T *p; / 栈顶栈顶 int sz; / 栈的大小栈

12、的大小public: Stack(int s) v=p=new Tsz=s; Stack() delete v; void push(T a) *p+ = a; T pop() return * - p ; int size() const return p-v; ;void main() int i; Stack sch(20); Stack sint(10);面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉19for (i= 0; i 10 ; i+) sint.push(i+1);for(i=0;i0 ; i-) if(sint.pop()

13、!=i) error() ; for(i=0;i20;i+) if(sch.pop()!=*) error();面向对象程序设计 中国科学技术大学计算机系 马建辉2012.3.4 非内联函数定义非内联函数定义一个值得注意的问题!一个值得注意的问题!面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉2 语法语法template返回值类型返回值类型 类模板名类模板名:成员函数名成员函数名(函数参数函数参数1,函数参数函数参数2,函数参数函数参数3)面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建

14、辉马建辉22非内联函数定义的非内联函数定义的StackStacktemplate class Stack T *v; / 栈底栈底 T *p; / 栈顶栈顶 int sz; / 栈的大小栈的大小public: Stack(int s; Stack() ; void push(T a); T pop() ; int size(); ;template Stack:Stack(int s) v=p=new Tsz=s;面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉23template Stack: Stack() delete v; templat

15、e void Stack: push(T a) *p+ = a; template T Stack: pop() return * - p ; template int Stack: size() const return p-v; ;面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉24 关于头文件关于头文件$对类来说,在创建非内联函数定义时,我们通常对类来说,在创建非内联函数定义时,我们通常把定义放在把定义放在.h.h文件中,而把实现放在文件中,而把实现放在. .cppcpp中。中。 (实际上是所谓的头文件原则:(实际上是所谓的

16、头文件原则:“在头文件中,不要放置分在头文件中,不要放置分配存储空间的任何东西配存储空间的任何东西”,为了防止在连接期间的多重定义,为了防止在连接期间的多重定义错误。)错误。)$对模板来说,即使是在创建非内联函数定义时,对模板来说,即使是在创建非内联函数定义时,模板的所有定义和实现都必须放入一个头文件中。模板的所有定义和实现都必须放入一个头文件中。 whywhy? 因为模板很特殊,在因为模板很特殊,在templatetemplate 之后的任何东西都意之后的任何东西都意味着编译器在当时不为它分配存储空间(即不编译成目标代味着编译器在当时不为它分配存储空间(即不编译成目标代码),而是一直处于等待

17、状态直到一个模板示例被告知。码),而是一直处于等待状态直到一个模板示例被告知。面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉25如果没有被实例化,模板不会被编译成目标代码:如果没有被实例化,模板不会被编译成目标代码:template class Stack T *v; / 栈底栈底 T *p; / 栈顶栈顶 int sz; / 栈的大小栈的大小public: Stack(int s; Stack() ; void push(T a); T pop() ; int size(); ;文件:文件:Stack.h面向对象程序设计面向对象程序设计 中国

18、科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉26template Stack:Stack(int s) v=p=new Tsz=s; template Stack: Stack() delete v; template void Stack: push(T a) *p+ = a; template T Stack: pop() return * - p ; template int Stack: size() const return p-v; ;文件:文件:Stack.cpp面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉27#i

19、nclude “Stack.h”void main() Stack si(10); si.push(1); / 连接错误连接错误文件文件:test.cpperror LNK2001: unresolved external symbol public: int _thiscall Stack:push(int) (?push?$stackHQAEHXZ)发生连接错误:发生连接错误:面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉28From MSDN:lLinker Tools Error LNK2001lunresolved external

20、symbol symbollCode will generate this error message if it references something (like a function, variable, or label) that the linker cant find in all the libraries and object files it searches. In general, there are two reasons this error occurs: what the code asks for doesnt exist (the symbol is sp

21、elled incorrectly or uses the wrong case, for example), or the code asks for the wrong thing (you are using mixed versions of the libraries?some from one version of the product, others from another version). lNumerous kinds of coding and build errors can cause LNK2001. Several specific causes are li

22、sted below, and some have links to more detailed explanations. 面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉2912.3.5 模板中的常量模板中的常量模板参数并不局限于类定义的类型,可以使用编译模板参数并不局限于类定义的类型,可以使用编译器内置类型。器内置类型。 tempate class Array ; 类型参数内置类型参数参数的默认值面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉30例:模板中的常量例:模板中的常量#includ

23、e ./require.h#include using namespace std;templateclass Array T arraysize; / 在实例化时,设置在实例化时,设置Array类的长度类的长度public: T& operator (int index) / 重载重载 实现关联数组实现关联数组 require(index = 0 & index size, Index out of range); return arrayindex; int length() const return size; ;面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学

24、计算机系 马建辉马建辉31class Number float f;public: Number(float ff = 0.0f) : f(ff) Number& operator=(const Number& n) / 重载赋值符重载赋值符 f = n.f; return *this; operator float() const return f; friend ostream& operator(ostream& os, const Number& x) return os x.f; ;面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉32t

25、emplateclass Holder Array* np;public: Holder() : np(0) T& operator(int i) require(0 = i & i size); if(!np) np = new Array; return np-operator (i); int length() const return size; Holder() delete np; ;面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉33int main() Holder h; for(int i = 0; i 20; i+) hi =

26、 i; for(int j = 0; j 20; j+) cout hj endl; /:面向对象程序设计 中国科学技术大学计算机系 马建辉3412.4 模板的派生模板的派生 面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉3512.4.1 从类派生模板从类派生模板 模板实际上是一组类,如果某一类定义了这模板实际上是一组类,如果某一类定义了这一组类的公共属性,则一组类的公共属性,则 模板可以从该类派生。模板可以从该类派生。class Base int i;protected: float f;public: void g() cout “g” e

27、ndl; ; template class derived:public Base面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉36T t; / ;void main() derived di; derived dc; di.g() ; / dc.g(); 面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉3712.4.2 从类模板派生模板从类模板派生模板templateclass Base int i;protected: T f;public: void g() cout “g” endl; ;

28、 类模板的基类如果也是模板,派生类模板的参数类模板的基类如果也是模板,派生类模板的参数表应包含基类模板的参数。表应包含基类模板的参数。面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉38template class derived:public Base T1 t; / ;void main() derived di; derived dc; di.g() ; / dc.g(); 面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉3912.4.2 从类模板派生模板从类模板派生模板(续续) 如果派生类没

29、有类型参数,或者说它的类型参如果派生类没有类型参数,或者说它的类型参数与基类的类型参数相同时,派生类地模板参数只数与基类的类型参数相同时,派生类地模板参数只要包含基类的模板参数就可以了要包含基类的模板参数就可以了template class C:public Base / 模板模板C的参数与基类相同的参数与基类相同 T c; / ;面向对象程序设计 中国科学技术大学计算机系 马建辉4012.5 函数模板函数模板实际上是定义了一组函数实际上是定义了一组函数面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉4112.5.1 函数模板的定义函数模板的定义

30、template 返回值类型返回值类型 函数名(函数参数表)函数名(函数参数表) /函数模板的定义函数模板的定义面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉42例例1:求两个对象间的最大值:求两个对象间的最大值template T max(T a, T b) return ab?a:b;这里这里T可以是可以是 int, char ,float, 或者任何重载了或者任何重载了算符的对象。算符的对象。面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉43例例2:关于模板参数:关于模板参数templat

31、e void f() / error, 函数参数列表中无函数模板参数函数参数列表中无函数模板参数T T a; / 面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉4412.5.2 函数模板的实例化函数模板的实例化 函数模板的实例化不需要用户显式进行,而函数模板的实例化不需要用户显式进行,而是在函数调用时由编译器来处理。是在函数调用时由编译器来处理。void main() int a, b; char c, d; int m1 = max(a,b); /调用调用max(int a, int b); char m2=max(c,d); / 调用调用max(char c,char d);面向对象程序设计面向对象程序设计 中国科学技术大学计算机系中国科学技术大学计算机系 马建辉马建辉45n 应保证函数调用时的参数与模板参数正好匹配,应保证函

温馨提示

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

评论

0/150

提交评论