1、第第7章章 运算符重载运算符重载2第第7章运算符重载章运算符重载本章学习要点本章学习要点v为什么要进行运算符重载为什么要进行运算符重载 v运算符重载的方法运算符重载的方法 v重载运算符的规则重载运算符的规则v运算符重载函数作为类成员函数和友元函数运算符重载函数作为类成员函数和友元函数v重载双目运算符重载双目运算符v重载单目运算符重载单目运算符v重载流插入运算符和流提取运算符重载流插入运算符和流提取运算符v不同类型数据间的转换不同类型数据间的转换3第第7章运算符重载章运算符重载v函数重载函数重载,就是赋给同一个函数名多个含义。,就是赋给同一个函数名多个含义。v运算符重载运算符重载是指同一个运算符
2、可以施加于不同是指同一个运算符可以施加于不同类型的操作数上面。类型的操作数上面。4class Moneypublic:Money(int y=0,int j=0,int f=0)yuan=y;jiao=j;fen=f;optimize();void Display(string);private:int yuan,jiao,fen;void Optimize();/优化函数优化函数;void Money:Optimize()if(fen=10)jiao+;fen-=10;if(jiao=10)yuan+;jiao-=10;void Money:Display(string str)cout s
3、tr =yuan .jiao fen¥=10)jiao+;fen-=10;if(jiao=10)yuan+;jiao-=10;void Money:Display(string str)cout str =yuan .jiao fen¥=10)jiao+;fen-=10;if(jiao=10)yuan+;jiao-=10;void Money:Display(string str)cout str =yuan .jiao fen¥endl;Money Money:MoneyAdd(Money&c2)return Money(yuan+c2.yuan,jiao+c2.jiao,fen+c2.fe
4、n);int main()Money cost1(300,5,6),cost2(105,7,6),total1;total1=cost1.MonetAdd(cost2);total1.Display(total1=cost1+cost2);return 0;77.1 为什么要进行运算符重载为什么要进行运算符重载但我们但我们希望希望在程序中在程序中直接用运算符直接用运算符“+”对对Money类的对象进行相加运算。类的对象进行相加运算。total1=cost1+cost2;对运算符对运算符“+”进行重载以后,就可以进行重载以后,就可以这样书写了。这样书写了。87.1 为什么要进行运算符重载为什么要
5、进行运算符重载v有了针对自定义类型数据的运算符重载有了针对自定义类型数据的运算符重载,不仅使我们编程时感到十分方便,而,不仅使我们编程时感到十分方便,而且写出的表达式与数学表达式很相似,且写出的表达式与数学表达式很相似,符合人们的习惯。符合人们的习惯。97.2 运算符重载的方法运算符重载的方法v重载运算符的函数的一般格式如下:重载运算符的函数的一般格式如下:函数类型函数类型 operator运算符名称运算符名称(形参列表形参列表)对运算符的重载处理对运算符的重载处理 函数名函数名函数名是由函数名是由operatoroperator和运算符组成,和运算符组成,如如operator+operato
6、r+意思是对运算符意思是对运算符“+”重载。重载。重载运算符的函数重载运算符的函数可以是可以是类的成员函数类的成员函数,也,也可以是可以是类的友元函数类的友元函数,还可以是既非类的成,还可以是既非类的成员函数也非类的友元函数的员函数也非类的友元函数的普通函数普通函数10【例【例7-1】对对“+”运算符进行重载来实现运算符进行重载来实现两个两个Money类对象的加法运算。类对象的加法运算。7.2 运算符重载的方法运算符重载的方法11#include#include using namespace std;class Moneypublic:Money(int y=0,int j=0,int f=
7、0);Money operator+(Money&);void Display(string);private:int yuan,jiao,fen;void Optimize();void Money:Optimize()if(fen=10)jiao+;fen-=10;if(jiao=10)yuan+;jiao-=10;Money:Money(int y,int j,int f)yuan=y;jiao=j;fen=f;Optimize();Money Money:operator+(Money&c2)return Money(yuan+c2.yuan,jiao+c2.jiao,fen+c2.f
8、en);void Money:Display(string str)cout str =yuan .jiao fen¥必须重载为类的成必须重载为类的成员函数员函数,必须重载为类的友元函数。必须重载为类的友元函数。227.4 运算符重载函数作为类的运算符重载函数作为类的成员函数和友元函数成员函数和友元函数v7.4.1运算符重载函数作为类的成员函数运算符重载函数作为类的成员函数v7.4.2运算符重载函数作为类的友元函数运算符重载函数作为类的友元函数237.4.1运算符重载函数作为类运算符重载函数作为类的成员函数的成员函数v将运算符重载函数定义为类的成员函数的原将运算符重载函数定义为类的成员函数的原
9、型在类的内部声明格式如下:型在类的内部声明格式如下:class 类名类名 返回类型返回类型 operator 运算符运算符(形参表形参表);v在类外定义运算符重载函数的格式如下:在类外定义运算符重载函数的格式如下:返回类型返回类型 类名类名:operator运算符运算符(形参表形参表)函数体函数体24【例例7-27-2】通过运算符重载为类的成员函数来实现通过运算符重载为类的成员函数来实现两个有理数对象的加、减、乘和除运算。两个有理数对象的加、减、乘和除运算。#include#include#include#include using namespace std;using namespace
10、std;class rational class rational /声明有理数类声明有理数类public:public:rational(int x=0,int y=1);rational(int x=0,int y=1);/构造函数构造函数 void print();void print();rational rational operator+(operator+(rational arational a););/重载运算符重载运算符+rationalrational operator-operator-(rational arational a););/重载运算符重载运算符-priva
11、te:private:int num,den;int num,den;void optimi();void optimi();/优化有理数函数优化有理数函数25void rational:optimi()void rational:optimi()/定义有理数优化函数定义有理数优化函数 int gcd;int gcd;if(num=0)if(num=0)/若分子为若分子为0 0,则置分母为,则置分母为1 1后返回后返回 den=1;return;den=1;return;gcd=(abs(num)abs(den)?abs(gcd=(abs(num)abs(den)?abs(denden):ab
12、s():abs(numnum););if(gcd=0)return;if(gcd=0)return;/若为若为0 0,则返回,则返回 for(int i=gcd;i1;i-)for(int i=gcd;i1;i-)/用循环找最大公约数用循环找最大公约数 if(num%i=0)&(den%i=0)break;if(num%i=0)&(den%i=0)break;num/=i;num/=i;/i i为最大公约数为最大公约数,将分子、分母均整除它将分子、分母均整除它,重新赋值重新赋值 den/=i;den/=i;/若分子和分母均为负数,则结果为正,所以均改为正若分子和分母均为负数,则结果为正,所以均
13、改为正 if(num0&den0)num=-num;den=-den;if(num0&den0)num=-num;den=-den;else if(num0|den0)else if(num0|den0)/若分子和分母中只有一个为负数,则调整为分子取负,分母取正若分子和分母中只有一个为负数,则调整为分子取负,分母取正 num=-abs(num);den=abs(den);num=-abs(num);den=abs(den);26void rational:print()/输出有理数输出有理数 coutnum;/当分子不为当分子不为0且分母不为且分母不为1时才显示时才显示/分母分母“if(num
14、!=0&den!=1)cout/denn;else coutn;7.4.1运算符重载函数作为运算符重载函数作为类的成员函数类的成员函数27rational rational:rational rational:operator+operator+(rational a)(rational a)/“+”运算符重载函数,根据前面所列的算法写出表达式运算符重载函数,根据前面所列的算法写出表达式 rational r;rational r;r.den=a.den r.den=a.den*den;den;r.num=a.numr.num=a.num*den+a.denden+a.den*num;num;
15、r.optimi();r.optimi();return r;return r;rational rational:rational rational:operator-operator-(rational a)(rational a)/“-”运算符重载函数,根据前面所列的算法写出表达式运算符重载函数,根据前面所列的算法写出表达式 rational r;rational r;r.den=a.den r.den=a.den*den;den;r.num=numr.num=num*a.den-dena.den-den*a.num;a.num;r.optimi();r.optimi();return
16、r;return r;28int main()rational r1(3,14),r2(4,14),r3,r4;r1.print();r2.print();r3=r1+r2;/使用重载了的运算符使用重载了的运算符“+”r3.print();r4=r1-r2;/使用重载了的运算符使用重载了的运算符“-”r4.print();return 0;7.4.1运算符重载函数作为运算符重载函数作为类的成员函数类的成员函数297.4.2运算符重载函数作为类的运算符重载函数作为类的友元函数友元函数v将运算符重载函数定义为类的友元函数,其原型在将运算符重载函数定义为类的友元函数,其原型在类的内部声明格式如下:类
17、的内部声明格式如下:class 类名类名 friend 返回类型返回类型 operator 运算符运算符(形参表形参表);v在类外定义友元运算符重载函数的格式如下:在类外定义友元运算符重载函数的格式如下:返回类型返回类型 operator运算符运算符(形参表形参表)函数体函数体30【例例7-37-3】将运算符将运算符“+”和和“-”重载为适合于有理数加减重载为适合于有理数加减法,重载函数不作为成员函数,而放在类外,作为法,重载函数不作为成员函数,而放在类外,作为rationalrational类的友元函数。类的友元函数。#include#include#include#include clas
18、s rational class rational/声明有理数类声明有理数类 public:public:/重载函数作为友元函数重载函数作为友元函数friendfriend rationalrational operator+operator+(rational a,rational brational a,rational b););/重载函数作为友元函数重载函数作为友元函数friendfriend rationalrational operator-operator-(rational a,rational brational a,rational b););private:private
19、:;31/定义作为友元函数的重载函数定义作为友元函数的重载函数rationalrational operator+operator+(rational a,rational b)(rational a,rational b)rational r;rational r;r.den=a.den r.den=a.den*b.den;b.den;r.num=a.num r.num=a.num*b.den+a.denb.den+a.den*b.num;b.num;r.optimi();r.optimi();return r;return r;/定义作为友元函数的重载函数定义作为友元函数的重载函数rati
20、onal rational operator-operator-(rational a,rational b)(rational a,rational b)rational r;rational r;r.den=a.den r.den=a.den*b.den;b.den;r.num=a.num r.num=a.num*b.den-a.denb.den-a.den*b.num;b.num;r.optimi();r.optimi();return r;return r;32int main()int main()rational r1(3,14),r2(4,14),r3,r4;rational r
21、1(3,14),r2(4,14),r3,r4;r1.print();r1.print();r2.print();r2.print();r3=r1+r2;r3=r1+r2;/使用重载了的运算符使用重载了的运算符“+”r3.print();r3.print();r4=r1-r2;r4=r1-r2;/使用重载了的运算符使用重载了的运算符“-”r4.print();r4.print();return 0;return 0;7.4.2运算符重载函数作为类的运算符重载函数作为类的友元函数友元函数337.5 重载双目运算符重载双目运算符v双目运算符(或称二元运算符)有两个双目运算符(或称二元运算符)有两个操
22、作数,通常在运算符的左右两侧,如操作数,通常在运算符的左右两侧,如x+y,t=3,a=b等。由于双目运算符有等。由于双目运算符有两个操作符,因此:两个操作符,因此:如果运算符重载函数为如果运算符重载函数为友元友元函数函数,则,则有两有两个参数。个参数。如果运算符重载函数为如果运算符重载函数为成员成员函数函数,则,则可以可以省略一个参数。省略一个参数。345.2 向上类型转换向上类型转换【例【例7-4】定义一个】定义一个Time类,用来存放做某件事所花费的类,用来存放做某件事所花费的时间,如小时分钟,分别重载运算符时间,如小时分钟,分别重载运算符“”用于用于求两段时间的和,重载运算符求两段时间的
23、和,重载运算符“”用于求两段时间的用于求两段时间的差。差。#include class Time public:Time();Time(int h,int m=0);friend Time operator+(Time&t1,Time&t2);friend Time operator-(Time&t1,Time&t2);void Show();private:int hours,minutes;Time:Time()hours=minutes=0;Time:Time(int h,int m)hours=h;minutes=m;355.2 向上类型转换向上类型转换void Time:Show()
24、couthours hours,minutes minutes;Time operator+(Time&t1,Time&t2)Time sum;sum.minutes=t1.minutes+t2.minutes;sum.hours=t1.hours+t2.hours+sum.minutes/60;sum.minutes%=60;return sum;Time operator-(Time&t1,Time&t2)Time dif;int x1,x2;x1=t2.hours*60+t2.minutes;x2=t1.hours*60+t1.minutes;dif.minutes=(x2-x1)%60
25、;dif.hours=(x2-x1)/60;return dif;365.2 向上类型转换向上类型转换int main()Time t1(5,30),t2(2,48),t3,t4;coutt1=;t1.Show();coutendl;coutt2=;t2.Show();coutendl;coutt3=t1+t2=;t3=t1+t2;t3.Show();coutendl;coutt4=t1-t2=;t4=t1-t2;t4.Show();coutendl;return 0;37指针悬挂指针悬挂【例例3-19】默认赋值运算符重载函数引起的指针悬挂默认赋值运算符重载函数引起的指针悬挂问题。问题。【例例
26、7-5】重载赋值运算符函数解决指针悬挂问题。】重载赋值运算符函数解决指针悬挂问题。#include#include class String /自定义字符串类自定义字符串类public:String();/默认构造函数默认构造函数 String(const char*src);/带参数的构造函数带参数的构造函数 String();/析构函数析构函数 const char*ToString()const return str;unsigned int Length()const return len;String&operator=(const String&right);private:cha
27、r*str;unsigned int len;String:String()/默认构造函数默认构造函数 len=0;str=new charlen+1;str0=0;String:String(const char*src)/带参数的构造函数带参数的构造函数 len=strlen(src);str=new charlen+1;if(!str)cerr Allocation Error!n;exit(1);strcpy(str,src);String:String()/析构函数析构函数 delete str;str=NULL;String&String:operator=(const Strin
28、g&right)if(&right!=this)int length=right.Length();if(len length)delete str;str=new charlength+1;assert(str!=0);for(int i=0;right.stri!=0;i+)stri=right.stri;stri=0;len=length;return*this;指针悬挂指针悬挂int main()String str1(Hi!),str2(Hello!);cout str1:str1.ToString()endl;cout str2:str2.ToString()endl;str1=s
29、tr2;cout str1:str1.ToString()endl;return 0;427.6 重载单目运算符重载单目运算符v单目运算符只有一个操作数,如单目运算符只有一个操作数,如!a,-b,&c,*p,-i,+i等。由于单目运算符等。由于单目运算符只有一个操作符,因此:只有一个操作符,因此:如果运算符重载函数为如果运算符重载函数为友元友元函数函数,则,则只能只能有一个参数。有一个参数。如果运算符重载函数为如果运算符重载函数为成员成员函数函数,则,则可以可以省略此参数省略此参数。435.2 向上类型转换向上类型转换【例例7-6】设计一个】设计一个Point类,有私有数据成员类,有私有数据成
30、员x和和y表示屏表示屏幕上的一个点的水平和垂直两个方向的坐标值,分别实幕上的一个点的水平和垂直两个方向的坐标值,分别实现对自增现对自增“+”和自减和自减“-”运算符的重载。运算符的重载。#includeusing namespace std;class Pointpublic:Point();Point(int vx,int vy);Point operator+();/前置自增前置自增 Point operator-();/前置自减前置自减 void display();private:int x,y;445.2 向上类型转换向上类型转换Point:Point()x=0;y=0;Point:
31、Point(int vx,int vy)x=vx;y=vy;void Point:display()cout(x,y)endl;Point Point:operator+();/前置自增前置自增 if(x640)x+;/不超过屏幕的横界不超过屏幕的横界 if(y0)x-;if(y0)y-;return*this;455.2 向上类型转换向上类型转换int main()Point p1(10,10),p2(150,150);coutp1=;p1.display();+p1;/测试前置自增测试前置自增 cout+p1=;p1.display();coutp2=;p2.display();-p2;/
32、测试前置自减测试前置自减 cout-p2=;p2.display();return 0;467.6 重载单目运算符重载单目运算符v在在C+中,前置单目运算符和后置单目运算符重载的中,前置单目运算符和后置单目运算符重载的主要区别就在于重载函数的形参。主要区别就在于重载函数的形参。v语法规定:语法规定:(1)前置前置单目运算符单目运算符重载为类的成员函数重载为类的成员函数时没有形参时没有形参,而,而后置后置单目运算符单目运算符重载为类的成员函数时重载为类的成员函数时需要有一需要有一个个int型形参型形参。这个。这个int型的参数在函数体内并不使用型的参数在函数体内并不使用,纯粹是用来区别前置与后置
33、,因此参数表中可以只,纯粹是用来区别前置与后置,因此参数表中可以只给出类型名,没有参数名。给出类型名,没有参数名。(2)前置前置单目运算符单目运算符重载为类的友元函数重载为类的友元函数时时有一个形有一个形参参,即为类的对象,而,即为类的对象,而后置后置单目运算符单目运算符重载为类的友重载为类的友元函数时元函数时需要有两个参数需要有两个参数,一个是类的对象,一个是,一个是类的对象,一个是int型形参。型形参。47v【例例7-7】在【例】在【例7-6】的基础上,增加后置单】的基础上,增加后置单目运算符目运算符“+”和和“-”的重载,其中将前置的重载,其中将前置和后置的和后置的“+”运算均重载为类的
34、成员函数运算均重载为类的成员函数,将前置和后置的,将前置和后置的“-”运算均重载为类的友运算均重载为类的友元函数。元函数。7.6 重载单目运算符重载单目运算符48#includeusing namespace std;class Pointpublic:Point();Point(int vx,int vy);Point operator+();/重载前置自增为类的成员函数重载前置自增为类的成员函数 Point operator+(int);/重载后置自增为类的成员函数重载后置自增为类的成员函数 /重载前置自减为类的友元函数重载前置自减为类的友元函数 friend Point operator
35、-(Point&p1);/重载后置自减为类的友元函数重载后置自减为类的友元函数 friend Point operator-(Point&p1,int);void display();private:int x,y;49Point:Point()x=0;y=0;Point:Point(int vx,int vy)x=vx;y=vy;void Point:display()cout(x,y)endl;Point Point:operator+()/前置自增前置自增 if(x640)x+;/不超过屏幕的横界不超过屏幕的横界 if(y480)y+;/不超过屏幕的竖界不超过屏幕的竖界 return*t
36、his;Point Point:operator+(int)/后置自增后置自增/先将当前对象通过复制构造函数临时保存起来先将当前对象通过复制构造函数临时保存起来 Point temp(*this);if(x640)x+;/不超过屏幕的横界不超过屏幕的横界 if(y0)p1.x-;if(p1.y0)p1.y-;return p1;Point operator-(Point&p1,int)/后置自减后置自减/先将当前对象通过复制构造函数临时保存起来先将当前对象通过复制构造函数临时保存起来 Point temp(p1);if(p1.x0)p1.x-;if(p1.y0)p1.y-;return tem
37、p;515.2 向上类型转换向上类型转换int main()Point p1(10,10),p2(150,150),p3(20,20),p4(160,160),p5;coutp1=;p1.display();+p1;/测试前置自增测试前置自增 cout+p1=;p1.display();coutp3=;p3.display();p5=p3+;/测试后置自增测试后置自增 cout p3+=;p3.display();coutp5=p3+=;p5.display();coutp2=;coutp2=;p2.display();p2.display();-p2;-p2;/测试前置自减测试前置自减 co
38、ut-p2=;cout-p2=;p2.display();p2.display();coutp4=;coutp4=;p4.display();p4.display();p5=p4-;p5=p4-;/测试后置自增测试后置自增 cout p4-=;cout p4-=;p4.display();p4.display();cout p5=p4-=;cout p5=p4-=;p5.display();p5.display();return 0;return 0;527.7 重载流插入运算符和重载流插入运算符和流提取运算符流提取运算符v在类库提供的头文件中已经对在类库提供的头文件中已经对“”进行了重载,使
39、之作为流插入运算符和进行了重载,使之作为流插入运算符和流提取运算符,能用来输出和输入流提取运算符,能用来输出和输入C+标准类标准类型的数据。型的数据。v用户自己定义的类型的数据,是不能直接用用户自己定义的类型的数据,是不能直接用“”来输出和输入的。如果想用来输出和输入的。如果想用它们输出和输入自己定义的类型的数据,就必它们输出和输入自己定义的类型的数据,就必须对它们进行重载。须对它们进行重载。537.7 重载流插入运算符和流提重载流插入运算符和流提取运算符取运算符v对对“”重载的函数形式如下:重载的函数形式如下:ostream&ostream&operateor operateor opera
40、teor (istream&,(istream&,自定义类自定义类););在重载时要注意下面两点:在重载时要注意下面两点:v(1)要对)要对“”运算符进行重载,运算符进行重载,必须必须重载为类的友元函数。重载为类的友元函数。v(2)重载的)重载的友元函数的返回类型友元函数的返回类型应是应是ostream对象对象或或istream对象的对象的引用引用,即,即ostream&或或istream&。7.7 重载流插入运算符和流提重载流插入运算符和流提取运算符取运算符v(1)要对)要对“”运算符进行重载运算符进行重载,必须重载为类的友元函数。,必须重载为类的友元函数。cout t;或或 operato
41、r(cout,t);void operator(ostream&out,Timer&t)out t.hours hours,t.minutes minutes;7.7 重载流插入运算符和流提重载流插入运算符和流提取运算符取运算符v(2)重载的友元函数的返回类型应是)重载的友元函数的返回类型应是ostream对象或对象或istream对象的引用,即对象的引用,即ostream&或或istream&。看下面的语句:看下面的语句:int x=5,y=6;cout x y;C+从左到右读取输出语句,这意味着它等从左到右读取输出语句,这意味着它等同于:同于:(cout x)y;565.2 向上类型转换向
42、上类型转换【例例7-8】对于】对于Time类,在【例类,在【例7-4】的基础上,增加重载】的基础上,增加重载流插入运算符流插入运算符“”,用,用“cout”输入输入Time类的对象。类的对象。#include class Timepublic:Time();Time(int h,int m=0);friend Time operator+(Time&t1,Time&t2);friend Time operator-(Time&t1,Time&t2);friend ostream&operator(istream&in,Time&t);private:int hours;int minutes;
43、575.2 向上类型转换向上类型转换Time:Time()hours=minutes=0;Time:Time(int h,int m)hours=h;minutes=m;Time operator+(Time&t1,Time&t2)Time sum;sum.minutes=t1.minutes+t2.minutes;sum.hours=t1.hours+t2.hours+sum.minutes/60;sum.minutes%=60;return sum;Time operator-(Time&t1,Time&t2)Time dif;int x1,x2;x1=t2.hours*60+t2.min
44、utes;x2=t1.hours*60+t1.minutes;dif.minutes=(x2-x1)%60;dif.hours=(x2-x1)/60;return dif;585.2 向上类型转换向上类型转换ostream&operator(ostream&out,Time&t)outt.hours hours,t.minutes(istream&in,Time&t)coutt.hourst.minutes;return in;595.2 向上类型转换向上类型转换int main()Time t1,t2,t3,t4;cint1t2;coutt1=t1n;coutt2=t2n;t3=t1+t2;
45、coutt3=t1+t2=t3n;t4=t1-t2;coutt4=t1-t2=t4n;return 0;607.8 不同类型数据间的转换不同类型数据间的转换v7.8.1系统预定义类型间的转换系统预定义类型间的转换v7.8.2转换构造函数转换构造函数v7.8.3类型转换函数类型转换函数617.8.1系统预定义类型间的转换系统预定义类型间的转换vC+提供了两种转换方式提供了两种转换方式:一种是一种是隐式类型转换隐式类型转换(或称标准类型转换)(或称标准类型转换)另一种是另一种是显式类型转换显式类型转换(或称强制类型转换(或称强制类型转换)627.8.1系统预定义类型间的转换系统预定义类型间的转换v
46、1.隐式类型转换隐式类型转换:主要主要注意注意以下几点:以下几点:(1)在)在C+中,将一个标准类型变量的值赋中,将一个标准类型变量的值赋给另一个标准类型变量时,如果这两种类型给另一个标准类型变量时,如果这两种类型兼容,则兼容,则C+自动将这个值转换为接收变量自动将这个值转换为接收变量的类型。的类型。(2)如果一个运算符两边的运算数类型不同)如果一个运算符两边的运算数类型不同,先要将其转换为相同的类型,即较低类型,先要将其转换为相同的类型,即较低类型转换为较高类型,然后再参加运算。转换为较高类型,然后再参加运算。637.8.1系统预定义类型间的转换系统预定义类型间的转换v1.隐式类型转换隐式类
47、型转换:主要主要注意注意以下几点:以下几点:(3)当较低类型的数据转换为较高类型时,)当较低类型的数据转换为较高类型时,一般只是形式上有所改变,一般只是形式上有所改变,而不影响数据的而不影响数据的实质内容,而较高类型的数据转换为较低类实质内容,而较高类型的数据转换为较低类型时则可能有些数据丢失。型时则可能有些数据丢失。(4)如果两个)如果两个float型数参加运算,虽然它们型数参加运算,虽然它们类型相同,但仍要先转成类型相同,但仍要先转成double型再进行运型再进行运算,结果亦为算,结果亦为double型。型。647.8.1系统预定义类型间的转换系统预定义类型间的转换v 2.显式类型转换显式
48、类型转换v C+提供显式类型转换,程序员在程序提供显式类型转换,程序员在程序中将一种类型的数据转换为另一种指定类中将一种类型的数据转换为另一种指定类型的数据,其形式为:型的数据,其形式为:类型名类型名(表达式表达式)如:如:int(89.5)int(89.5)其作用是将其作用是将89.5转换为整型数转换为整型数89。65v对于用户自己声明的类型对于用户自己声明的类型,编译系统并不知编译系统并不知道怎样进行转换。道怎样进行转换。v解决这个问题的关键解决这个问题的关键是让编译系统知道怎样是让编译系统知道怎样去进行这些转换,去进行这些转换,需要需要定义专门的函数定义专门的函数来处来处理。理。7.8
49、不同类型数据间的转换不同类型数据间的转换667.8.2 转换构造函数转换构造函数v通常把只有一个形参的构造函数,通常把只有一个形参的构造函数,称为称为转换构造函数。转换构造函数。利用它,可以将一个其利用它,可以将一个其他类型的数据转换成一个指定的类的对他类型的数据转换成一个指定的类的对象。象。677.8.2 转换构造函数转换构造函数先回顾一下以前学习过的几种构造函数:先回顾一下以前学习过的几种构造函数:默认构造函数:默认构造函数:Rational();Rational();/没有参数没有参数用于初始化的构造函数:用于初始化的构造函数:Rational(int x,int y);Rational
50、(int x,int y);用于复制对象的复制构造函数:用于复制对象的复制构造函数:Rational(Rational&c);Rational(Rational&c);687.8.2 转换构造函数转换构造函数v转换构造函数转换构造函数只有一个形参,如只有一个形参,如 Rational(Rational(intint x)x)numenume=x;=x;denodeno=1;=1;其作用是其作用是将将intint型的参数型的参数x x转换成转换成RationalRational类类的对象的对象,将,将x x作为有理数的分子,分母为作为有理数的分子,分母为1 1。697.8.2 转换构造函数转换构