第3章C++进阶

上传人:z**** 文档编号:258615178 上传时间:2022-02-23 格式:PPT 页数:25 大小:168.50KB
返回 下载 相关 举报
第3章C++进阶_第1页
第1页 / 共25页
第3章C++进阶_第2页
第2页 / 共25页
第3章C++进阶_第3页
第3页 / 共25页
第3章C++进阶_第4页
第4页 / 共25页
第3章C++进阶_第5页
第5页 / 共25页
点击查看更多>>
资源描述

《第3章C++进阶》由会员分享,可在线阅读,更多相关《第3章C++进阶(25页珍藏版)》请在金锄头文库上搜索。

1、第3章C+进阶 3.1 多态和虚函数 3.2 运算符重载 3.3 输入输出流库 3.4 模板 3.1多态和虚函数 3.1.1虚函数 例Ex_VirtualFunc 虚函数的使用。#include class CShape public: virtual float area() return 0.0;class CTriangle:public CShape public: CTriangle(float h, float w) H=h;W=w; float area() return (float)(H * W * 0.5 ); private:float H, W;class CCircl

2、e:public CShapepublic:CCircle(float r)R=r;float area()return (float)(3.14159265 * R * R);private:float R;void main()CShape *s2;s0 = new CTriangle(3,4);coutarea()endl;s1 = new CCircle(5);coutarea()endl;运行结果为:678.5398 3.1多态和虚函数说明:(1)虚函数在重新定义时参数的个数和类型必须和基类中的虚函数完全匹配,这一点和函数重载完全不同。(2)虚函数所具备的上述功能,只有通过基类指针才

3、可实现。虚函数在用对象名和成员运算符以正常方式调用时,不能达到其效果。(3)如果不使用new来创建相应的派生类对象,也可用下列方法来实现:void main()CShape *p1, *p2;CTriangle tri(3, 4);CCircle cir(5);p1 = &tri;p2 = ○coutarea()endl;coutarea()endl; (4)虚函数必须是类的一个成员函数,不能是友元函数,不能是静态的成员函数。(5)可把析构函数定义为虚函数,但不能将构造函数定义为虚函数。通常在释放基类及其派生类中的动态申请的存储空间时,也要把析构函数定义为虚函数,以便实现撤消对象时的多

4、态性。 3.1多态和虚函数3.1.2纯虚函数和抽象类 定义一个基类时,会遇到这样的情况:无法定义基类中虚函数的具体实现,其实现完全依赖于其不同的派生类。例如,一个“形状类”由于没有确定的具体形状,因此其计算面积的函数也就无法实现。这时可将基类中的虚函数声明为纯虚函数。 声明纯虚函数的一般格式为:virtual () = 0; 它与一般虚函数不同的是:在纯虚函数的形参表后面多了个“=0”。把函数名赋于0,本质上是将指向函数的指针的初值赋为0。需要说明的是,纯虚函数不能有具体的实现代码。 抽象类是指至少包含一个纯虚函数的特殊的类。它本身不能被实例化,也就是说不能声明一个抽象类的对象。必须通过继承得

5、到派生类后,在派生类中定义了纯虚函数的具有实现代码,才能获得一个派生类的对象。 与虚函数使用方法相同,也可以声明指向抽象类的指针,虽然该指针不能指向任何抽象类的对象,但可以通过该指针获得对派生类成员函数的调用。事实上,纯虚函数是一个特殊的虚函数。 3.2运算符重载 3.2.1运算符重载的语法 :operator () / 函数体运算符重载函数的函数是以特殊的关键字operator开始的,因而编译器很容易与其他的函数名区分开来。重载的运算符必须是合法的运算符。说明:(1)当用成员函数实现双目运算符的重载时,运算符的左操作数一定是对象,右操作数作为调用运算符重载函数的参数,参数可以是对象、对象的引

6、用或是其他类型的参数。(2)不是所有的运算符都可以重载。不允许重载的运算符除三目运算符“?:”外,还有成员操作符“.”、成员指针取值操作符“*”、作用域操作符“:”以及sizeof运算符。(3)只能对已定义了的运算符进行重载,而且当重载一个运算符时,该运算符的操作数个数、优先级和结合性是不能改变的。3.2运算符重载例Ex_Complex 运算符的简单重载。#include class CComplexpublic:CComplex(double r = 0, double i = 0) realPart = r;imagePart = i;void print()cout该复数实部 = rea

7、lPart, 虚部 = imagePartendl;CComplex operator + (CComplex &c);/ 重载运算符+CComplex operator + (double r);/ 重载运算符+private:double realPart;/ 复数的实部double imagePart;/ 复数的虚部;CComplex CComplex:operator + (CComplex &c) / 参数是CComplex引用对象CComplex temp;temp.realPart = realPart + c.realPart;temp.imagePart = imagePar

8、t + c.imagePart;return temp; 3.2运算符重载CComplex CComplex:operator + (double r)/ 参数是double类型数据CComplex temp;temp.realPart = realPart + r;temp.imagePart = imagePart;return temp;void main()CComplex c1(12,20), c2(50,70), c;c = c1 + c2;c.print();c = c1+ 20;c.print();运行结果为:该复数实部 = 62, 虚部 = 90该复数实部 = 32, 虚部

9、= 20 对运算符“+”作了两次重载,一个用于实现两个复数的加法,另一个用于实现一个复数与一个实数的加法。当重载一个运算符时,必须定义该运算符要完成的具体操作,而且当运算符重载函数是类的成员函数时,该函数的形参个数要比运算符操作数个数少一个,双目运算符重载的成员函数只有一个参数,单目运算符重载的成员函数没有参数。 3.2运算符重载3.2.2赋值运算符的重载 对象的成员中有数组或动态的数据类型时,就不能直接相互赋值,否则在程序的编译或执行过程中出现编译或运行错误。例如:class Cdemopublic:CDemo(char *s)ps = new charstrlen(s) + 1;strcp

10、y(ps, s);CDemo()if (ps) delete ps;void print()coutpsendl;private:char *ps;void main()CDemo d1(Key), d2(Mouse);d1 = d2; 程序运行到“d1 = d2”时发生运行错误。因此,必须重载“=”运算符,它与其他运算符的重载相同。 3.2运算符重载例Ex_Evaluate 赋值运算符的重载。#include #include class CDemopublic:/ 同上面的斜体部分代码CDemo& operator = (CDemo &a)/ 赋值运算符重载if (ps) delete p

11、s;if (a.ps)ps = new charstrlen(a.ps) + 1;strcpy(ps, a.ps);else ps = 0;return *this;private:char *ps;void main()CDemo d1(Key), d2(Mouse);d1 = d2;d1.print(); 运行结果为:Mouse 赋值运算符不能重载为友元函数,只能是一个非静态成员函数。 3.2运算符重载3.2.3提取和插入运算符重载 C+允许用户重载“”和“”运算符,以便用户利用标准的输入输出流来输入输出自己定义的数据类型(包括类),实现对象的输入输出。重载这两个运算符时最好将重载声明为类

12、的友元函数,以便访问类中的私有成员。友元重载的一般格式如下:friend operator ()/ 单目运算符重载 / 函数体friend operator ()/ 双目运算符重载 / 函数体对于单目运算符的友元重载函数,只有一个形参,形参类型可以是类的对象,可以是引用,这取决于不同的运算符。对于双目运算符的友元重载函数来说,它有两个形参,这两个形参中必须有一个是类的对象。需要说明的是,=、()、和-运算符不能用友元来重载。 3.2运算符重载例Ex_ExtractAndInsert 提取和插入运算符的重载。#include class CStudentpublic:friend ostream

13、& operator ( istream& is, CStudent& stu );private:char strName10;/ 姓名char strID10;/ 学号float fScore3;/ 三门成绩;ostream& operator ( ostream& os, CStudent& stu )osendl学生信息如下:endl;os姓名:stu.strNameendl;os学号:stu.strIDendl;os成绩:stu.fScore0,tstu.fScore1,tstu.fScore2 ( istream& is, CStudent& stu )cout请输入学生信息end

14、l;coutstu.strName;coutstu.strID;coutstu.fScore0stu.fScore1stu.fScore2;return is;void main()CStudent one;cinone;cout”和插入运算符“”来进行输入输出操作的,而且系统还会自动地完成数据类型的转换。 3.3输入输出流库3.3.2cout和cin输出流(cout) cout可以输出一个整数、实数、字符及字符串,cout中的插入符“ .提取符“”可以连续写多个,每个后面跟一个表达式,该表达式通常是获得输入值的变量或对象。要求用户从键盘上输入三个整数。输入时,必须在三个数值之间加上一些空格来

15、分隔,空格的个数不限,最后用回车键结束输入;或者在每个数值之后按回车键。格式算子oct、dec和hex 格式算子oct、dec和hex能分别将输入或输出的数值转换成八进制、十进制及十六进制。 3.3输入输出流库输入输出过程中发现操作错误,流就会将发生的错误记录下来。用户可以使用错误检测功能,检测和查明错误发生的原因和性质,然后调用clear函数清除错误状态,使流能够恢复处理。在ios类中,定义了一个公有枚举成员io_state来记录各种错误的性质:enum io_state goodbit= 0 x00, / 正常eofbit = 0 x01, / 已达到文件尾failbit = 0 x02,

16、 / 操作失败badbit = 0 x04 / 非法操作;在ios类中又定义了检测上述流状态的下列成员函数:int ios:rdstate();/ 返回当前的流状态int ios:bad();/ 如果badbit位被置位,返回非0void ios:clear(int);/ 清除错误状态int ios:eof();/ 返回非0表示提取操作已到文件尾int ios:fail();/ 如果failbit位被置位,返回非0int ios:good (); / 操作正常时,返回非0 当输入一个浮点数,会自动进行类型转换。只有键入字符或字符串时,才会产生输入错误,但由于cin有缓冲区,输入的字符或字符串会暂时保存到它的缓冲区中,因此为了能继续提取用户的输入,必须先将缓冲区清空。 3.3输入输出流库3.3.4使用输入输出成员函数 输入操作的成员函数 数据的输入/输出可以分为三大类:字符类、字符串和数据。(1) 使用get和getline函数int get();istream& get( char& rch );istream& get( char* pch, int nCount, char del

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

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