运算符重载,异常处理,输入输出流库.ppt

上传人:文库蛋蛋多 文档编号:2840013 上传时间:2023-02-26 格式:PPT 页数:79 大小:432.50KB
返回 下载 相关 举报
运算符重载,异常处理,输入输出流库.ppt_第1页
第1页 / 共79页
运算符重载,异常处理,输入输出流库.ppt_第2页
第2页 / 共79页
运算符重载,异常处理,输入输出流库.ppt_第3页
第3页 / 共79页
运算符重载,异常处理,输入输出流库.ppt_第4页
第4页 / 共79页
运算符重载,异常处理,输入输出流库.ppt_第5页
第5页 / 共79页
点击查看更多>>
资源描述

《运算符重载,异常处理,输入输出流库.ppt》由会员分享,可在线阅读,更多相关《运算符重载,异常处理,输入输出流库.ppt(79页珍藏版)》请在三一办公上搜索。

1、模板,函数模板类模板,函数模板,函数模板可以用来创建一个通用功能的函数,以支持多种不同形参,进一步简化重载函数的函数体设计。声明方法:template 函数声明,函 数 模 板,求绝对值函数的模板,#includeusing namespace std;templateT abs(T x)return x0?-x:x;void main()int n=-5;double d=-5.5;coutabs(n)endl;coutabs(d)endl;,函 数 模 板,运行结果:55.5,求绝对值函数的模板分析,编译器从调用abs()时实参的类型,推导出函数模板的类型参数。例如,对于调用表达式abs(

2、n),由于实参n为int型,所以推导出模板中类型参数T为int。当类型参数的含义确定后,编译器将以函数模板为样板,生成一个函数:int abs(int x)return x0?-x:x;,函 数 模 板,类模板的作用,使用类模板使用户可以为类声明一种模式,使得类中的某些数据成员、某些成员函数的参数、某些成员函数的返回值,能取任意类型(包括基本类型的和用户自定义类型)。,类 模 板,类模板的声明,类模板:template class 类名类成员声明如果需要在类模板以外定义其成员函数,则要采用以下的形式:template 类型名 类名:函数名(参数表),类 模 板,例类模板应用举例,#includ

3、e#include using namespace std;/结构体Studentstruct Student int id;/学号 float gpa;/平均分;,类 模 板,template/类模板:实现对任意类型数据进行存取class Store private:T item;/用于存放任意类型的数据 int haveValue;/用于标记item是否已被存入内容 public:Store(void);/默认形式(无形参)的构造函数 T GetElem(void);/提取数据函数 void PutElem(T x);/存入数据函数;/默认形式构造函数的实现template Store:S

4、tore(void):haveValue(0),8,template/提取数据函数的实现T Store:GetElem(void)/如果试图提取未初始化的数据,则终止程序 if(haveValue=0)cout/存入数据函数的实现 void Store:PutElem(T x)haveValue+;/将haveValue 置为 TRUE,表示item中已存入数值 item=x;/将x值存入item,9,void main(void)Student g=1000,23;Store S1,S2;Store S3;Store D;S1.PutElem(3);S2.PutElem(-7);cout S

5、1.GetElem()S2.GetElem()endl;S3.PutElem(g);cout The student id is S3.GetElem().id endl;cout Retrieving object D;cout D.GetElem()endl;/输出对象D的数据成员/由于D未经初始化,在执行函数D.GetElement()时出错,10,问题举例复数的运算,class complex/复数类声明public:complex(double r=0.0,double i=0.0)/构造函数 real=r;imag=i;void display();/显示复数的值private:d

6、ouble real;double imag;,运算符重载,问题举例复数的运算,用“+”、“-”能够实现复数的加减运算吗?实现复数加减运算的方法 重载“+”、“-”运算符,运算符重载,运算符重载的实质,运算符重载是对已有的运算符赋予多重含义必要性C+中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)实现机制将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。编译系统对重载运算符的选择,遵循函数重载的选择原则。,运算符重载,运算符重载,规则和限制,可以重载C+中除下列运算符外的所有运算符:.*:?:只能重载C+语言中已有的运算符,不可臆造新的。

7、不改变原运算符的优先级和结合性。不能改变操作数个数。经重载的运算符,其操作数中至少应该有一个是自定义类型。,两种形式,重载为类成员函数。重载为友元函数。,运算符重载,运算符函数,声明形式函数类型 operator 运算符(形参).重载为类成员函数时 参数个数=原操作数个数-1(后置+、-除外)重载为友元函数时 参数个数=原操作数个数,且至少应该有一个自定义类型的形参。,运算符重载,运算符成员函数的设计,双目运算符 B如果要重载 B 为类成员函数,使之能够实现表达式 oprd1 B oprd2,其中 oprd1 为A 类对象,则 B 应被重载为 A 类的成员函数,形参类型应该是 oprd2 所属

8、的类型。经重载后,表达式 oprd1 B oprd2 相当于 oprd1.operator B(oprd2),运算符重载,运算符重载,例 8.1,将“+”、“-”运算重载为复数类的成员函数。规则:实部和虚部分别相加减。操作数:两个操作数都是复数类的对象。,#includeusing namespace std;class complex/复数类声明public:/外部接口complex(double r=0.0,double i=0.0)real=r;imag=i;/构造函数complex operator+(complex c2);/+重载为成员函数complex operator-(com

9、plex c2);/-重载为成员函数void display();/输出复数private:/私有数据成员double real;/复数实部double imag;/复数虚部;,19,complex complex:operator+(complex c2)/重载函数实现complex c;c.real=c2.real+real;c.imag=c2.imag+imag;return complex(c.real,c.imag);,20,complex complex:operator-(complex c2)/重载函数实现complex c;c.real=real-c2.real;c.imag

10、=imag-c2.imag;return complex(c.real,c.imag);,21,void complex:display()cout(real,imag)endl;void main()/主函数complex c1(5,4),c2(2,10),c3;/声明复数类的对象coutc1=;c1.display();coutc2=;c2.display();c3=c1-c2;/使用重载运算符完成复数减法coutc3=c1-c2=;c3.display();c3=c1+c2;/使用重载运算符完成复数加法coutc3=c1+c2=;c3.display();,22,程序输出的结果为:c1=

11、(5,4)c2=(2,10)c3=c1-c2=(3,-6)c3=c1+c2=(7,14),23,运算符成员函数的设计,前置单目运算符 U如果要重载 U 为类成员函数,使之能够实现表达式 U oprd,其中 oprd 为A类对象,则 U 应被重载为 A 类的成员函数,无形参。经重载后,表达式 U oprd 相当于 oprd.operator U(),运算符重载,运算符成员函数的设计,后置单目运算符+和-如果要重载+或-为类成员函数,使之能够实现表达式 oprd+或 oprd-,其中 oprd 为A类对象,则+或-应被重载为 A 类的成员函数,且具有一个 int 类型形参。经重载后,表达式 opr

12、d+相当于 oprd.operator+(0),运算符重载,例8.2,运算符前置+和后置+重载为时钟类的成员函数。前置单目运算符,重载函数没有形参,对于后置单目运算符,重载函数需要有一个整型形参。操作数是时钟类的对象。实现时间增加1秒钟。,运算符重载,/8_2.cpp#includeusing namespace std;class Clock/时钟类声明 public:/外部接口 Clock(int NewH=0,int NewM=0,int NewS=0);void ShowTime();Clock,27,Clock,28,/后置单目运算符重载Clock Clock:operator+(i

13、nt)/注意形参表中的整型参数 Clock old=*this;+(*this);return old;,29,/其它成员函数的实现略void main()Clock myClock(23,59,59);coutFirst time output:;myClock.ShowTime();coutShow myClock+:;(myClock+).ShowTime();coutShow+myClock:;(+myClock).ShowTime();,30,程序运行结果为:First time output:23:59:59Show myClock+:23:59:59Show+myClock:0:

14、0:1,31,异常处理的基本思想,异常处理的实现,抛掷异常的程序段.throw 表达式;.,捕获并处理异常的程序段try 复合语句catch(异常类型声明)复合语句catch(异常类型声明)复合语句,控制通过正常的顺序执行到达try语句,然后执行try块内的保护段。如果在保护段执行期间没有引起异常,那么跟在try块后的catch子句就不执行。程序从try块后跟随的最后一个catch子句后面的语句继续执行下去。,若有异常则从通过throw操作创建一个异常对象并抛掷。,catch子句按其在try块后出现的顺序被检查。匹配的catch子句将捕获并处理异常(或继续抛掷异常)。如果匹配的处理器未找到,则

15、运行函数terminate将被自动调用,其缺省功能是调用abort终止程序。,例12-1 处理除零异常,#includeint Div(int x,int y);void main()trycout5/2=Div(5,2)endl;cout8/0=Div(8,0)endl;cout7/1=Div(7,1)endl;,catch(int)coutexcept of deviding zero.n;coutthat is ok.n;int Div(int x,int y)if(y=0)throw y;return x/y;,程序运行结果如下:5/2=2except of deviding zero

16、.that is ok.,异常接口声明,可以在函数的声明中列出这个函数可能抛掷的所有异常类型。例如:void fun()throw(A,B,C,D);若无异常接口声明,则此函数可以抛掷任何类型的异常。不抛掷任何类型异常的函数声明如下:void fun()throw();,异常处理中的构造与析构,找到一个匹配的catch异常处理后:初始化参数。将从对应的try块开始到异常被抛掷处之间构造(且尚未析构)的,所有自动对象进行析构。从最后一个catch处理之后开始恢复执行。,例12-2 异常处理时的析构,#include void MyFunc(void);class Expt public:Expt

17、();Expt();const char*ShowReason()const return Expt类异常。;,class Demo public:Demo();Demo();Demo:Demo()cout 构造 Demo.endl;Demo:Demo()cout 析构 Demo.endl;,void MyFunc()Demo D;cout 在MyFunc()中抛掷Expt类异常。endl;throw Expt();int main()cout 在main函数中。endl;try cout 在try块中,调用MyFunc()。endl;MyFunc();,catch(Expt E)cout 在

18、catch异常处理程序中。endl;cout 捕获到Expt类型异常:;cout E.ShowReason()endl;catch(char*str)cout 捕获到其它的异常:str endl;cout 回到main函数。从这里恢复执行。endl;return 0;,程序运行时输出:在main函数中。在try块中,调用MyFunc()。构造 Demo.在MyFunc()中抛掷Expt类异常。析构 Demo.在catch异常处理程序中。捕获到Expt类型异常:Expt类异常。回到main函数。从这里恢复执行。,I/O流的概念,当程序与外界环境进行信息交换时,存在着两个对象,一个是程序中的对象,

19、另一个是文件对象。流是一种抽象,它负责在数据的生产者和数据的消费者之间建立联系,并管理数据的流动。程序建立一个流对象,并指定这个流对象与某个文件对象建立连接,程序操作流对象,流对象通过文件系统对所连接的文件对象产生作用。读操作在流数据抽象中被称为(从流中)提取,写操作被称为(向流中)插入。,输出流,最重要的三个输出流是ostreamofstreamostrstream。,输出流对象,通过派生类ostream_withassign支持预先定义的流对象:cout 标准输出cerr 标准错误输出,没有缓冲,发送给它的内容立即被输出。clog 类似于cerr,但是有缓冲,缓冲区满时被输出。,输出流对象

20、,ofstream类支持磁盘文件输出构造一个ofstream类的对象。在打开文件之前或之后可以指定ofstream对象接受二进制或文本模式数据。,输出流对象,如果在构造函数中指定一个文件名,当构造这个文件时该文件是自动打开的ofstream myFile(filename,iosmode);,输出流对象,可以在调用缺省构造函数之后使用open成员函数打开文件ofstream myFile;/声明一个静态输出文件流对象myFile.open(filename,iosmode);/打开文件,使流对象与文件建立联系ofstream*pmyFile=new ofstream;/建立一个动态的输出文件流

21、对象pmyFile-open(filename,iosmode);/打开文件,使流对象与文件建立联系,输出流对象,在一个由文件指示符标识的打开文件基础上构造一个ofstream对象。int fd=open(filename,dosmode);ofstream myFile1(fd);/Buffered mode(default)ofstream myFile2(fd,NULL,0);/Unbuffered mode,插入运算符(),插入()运算符是所有标准C+数据类型预先设计的。用于传送字节到一个输出流对象。,控制输出格式,控制输出宽度为了调整输出,可以通过在流中放入setw操纵符或调用wid

22、th成员函数为每个项指定输出宽度。,例11-1 使用width控制输出宽度,#include void main()double values=1.23,35.36,653.7,4358.24;for(int i=0;i4;i+)cout.width(10);cout valuesi n;,输出结果是:1.23 35.36 653.7 4358.24,#include void main()double values=1.23,35.36,653.7,4358.24;for(int i=0;i4;i+)cout.width(10);cout.fill(*);cout valuesi n;,输出

23、结果如下:*1.23*35.36*653.7*4358.24,例11-2 使用setw指定宽度,#include#include void main()double values=1.23,35.36,653.7,4358.24;char*names=Zoot,Jimmy,Al,Stan;for(int i=0;i4;i+)cout setw(6)namesi setw(10)valuesi endl;,输出流,运行结果如下:Zoot 1.23 Jimmy 35.36 Al 653.7 Stan 4358.24,例11-3 设置对齐方式,#include#include void main()

24、double values=1.23,35.36,653.7,4358.24;char*names=Zoot,Jimmy,Al,Stan;,for(int i=0;i4;i+)cout setiosflags(ios:left)setw(6)namesi resetiosflags(ios:left)setw(10)valuesi endl;输出结果如下:Zoot 1.23Jimmy 35.36Al 653.7Stan 4358.24,例11-4 控制输出精度,#include#include void main()double values=1.23,35.36,653.7,4358.24;

25、char*names=Zoot,Jimmy,Al,Stan;cout setiosflags(ios:scientific);,for(int i=0;i4;i+)cout setiosflags(ios:left)setw(6)namesi resetiosflags(ios:left)setw(10)setprecision(1)valuesi endl;该程序的输出结果如下:Zoot 1Jimmy 4e+001Al 7e+002Stan 4e+003,进制,dec、oct和hex操纵符设置输入和输出的缺省进制。,输出文件流成员函数,输出流成员函数有三种类型:与操纵符等价的成员函数。执行非

26、格式化写操作的成员函数。其它修改流状态且不同于操纵符或插入运算符的成员函数。,输出文件流成员函数,open函数把流与一个特定的磁盘文件关联起来。需要指定打开模式。put函数把一个字符写到输出流中。write函数把内存中的一块内容写到一个输出文件流中seekp和tellp函数操作文件流的内部指针close函数关闭与一个输出文件流关联的磁盘文件错误处理函数在写到一个流时进行错误处理,例11-5 向文件输出,#include struct Date int mo,da,yr;void main()Date dt=6,10,92;ofstream tfile(date.dat,ios:binary);

27、tfile.write(char*),二进制输出文件,以通常方式构造一个流,然后使用setmode成员函数,在文件打开后改变模式。使用ofstream构造函数中的模式参量指定二进制输出模式使用二进制操作符代替setmode成员函数:ofs binary;,输入流,重要的输入流类:istream类最适合用于顺序文本模式输入。cin是其派生类istream_withassign的对象。ifstream类支持磁盘文件输入。,输入流对象,如果在构造函数中指定一个文件名,在构造该对象时该文件便自动打开。ifstream myFile(filename,iosmode);在调用缺省构造函数之后使用open

28、函数来打开文件。ifstream myFile;/建立一个文件流对象myFile.open(filename,iosmode);/打开文件filename,提取运算符(),提取运算符()对于所有标准C+数据类型都是预先设计好的。是从一个输入流对象获取字节最容易的方法。ios类中的很多操纵符都可以应用于输入流。但是只有少数几个对输入流对象具有实际影响,其中最重要的是进制操纵符dec、oct和hex。,输入流成员函数,open函数把该流与一个特定磁盘文件相关联。get函数的功能与提取运算符()很相像,主要的不同点是get函数在读入数据时包括空白字符。(第6章介绍过)getline的功能是从输入流中

29、读取多个字符,并且允许指定输入终止字符,读取完成后,从读取的内容中删除终止字符。(第6章介绍过),输入流成员函数,read成员函数从一个文件读字节到一个指定的内存区域,由长度参数确定要读的字节数。如果给出长度参数,当遇到文件结束或者在文本模式文件中遇到文件结束标记字符时结束读取。,例11-6 文件读二进制记录,#include#include#include void main()struct double salary;char name23;employee;,ifstream is(payroll,ios:binary|ios:nocreate);if(is)is.read(char*)

30、,输入流成员函数,seekg函数用来设置输入文件流中读取数据位置的指针。tellg函数返回当前文件读指针的位置。close函数关闭与一个输入文件流关联的磁盘文件。,例11-7 设置位置指针,#include void main()char ch;ifstream tfile(payroll,ios:binary|ios:nocreate);if(tfile)tfile.seekg(8);,while(tfile.good())tfile.get(ch);if(!ch)break;cout ch;else cout ERROR:Cannot open file payroll.endl;,例11-8 读文件并显示其中空格的位置,#include void main()char ch;ifstream tfile(payroll,ios:binary|ios:nocreate);if(tfile),while(tfile.good())streampos here=tfile.tellg();tfile.get(ch);if(ch=)cout nPosition here is a space;else cout ERROR:Cannot open file payroll.endl;,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 建筑/施工/环境 > 项目建议


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号