版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第六章
自定义类型的运算清华大学郑莉学习目标理解运算符函数与运算符重载的概念;掌握典型运算符的重载方法。2目录6.1用函数实现对象的运算6.2运算符重载函数6.2.1运算符重载为成员函数6.2.2运算符重载为非成员函数3目录(续)6.3典型运算符的重载6.3.1重载乘法运算符6.3.2重载求相反数运算符6.3.3重载相等比较运算符6.3.4重载++运算符6.3.5重载赋值运算符6.3.6重载类型转换符6.3.7重载下标访问运算符46.1用函数实现对象的运算定义一种新的数据类型,就同时需要定义对这种类型数据的操作,最基本的方法就是定义一系列能够完成各种运算的函数。利用成员函数实现运算的优点是:函数中可方便地访问复数对象中的私有成员。
5例6-1:实现复数的加法运算—用成员函数
#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} Complexadd(Complexc); //复数与复数相加的函数 Complexadd(doubler); //复数与实数相加的函数
voidoutput();//用于输出复数的函数};
66.1用函数实现对象的运算ComplexComplex::add(Complexc){ returnComplex(real+c.real,image+c.image);}
ComplexComplex::add(doubler){ returnComplex(real+r,image);}
voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}76.1用函数实现对象的运算例6-1(续)例6-1(续)intmain(){ Complexa(1.5,2.8),b(-2.3,3.4); Complexc1,c2; c1=a.add(b); c2=b.add(4.5); c1.output(); c2.output(); return0;}86.1用函数实现对象的运算运行结果:(-0.8+6.2i)(2.2+3.4i)例6-1(续)6.1用函数实现对象的运算例6-2:实现复数的加法运算—用非成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput(); friendComplexadd(Complexc1,Complexc2); friendComplexadd(Complexc,doubler); friendComplexadd(doubler,Complexc); };106.1用函数实现对象的运算例6-2(续)voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
Complexadd(Complexc1,Complexc2){ returnComplex(c1.real+c2.real,c1.image+c2.image);}Complexadd(Complexc,doubler){ returnComplex(c.real+r,c.image);}116.1用函数实现对象的运算Complexadd(doubler,Complexc){ returnComplex(r+c.real,c.image);}
intmain(){ Complexa(1.5,2.8),b(-2.3,3.4); Complexc1,c2,c3; c1=add(a,b); c2=add(a,2.3); c3=add(3.2,b); c1.output(); c2.output(); c3.output(); return0;}126.1用函数实现对象的运算例6-2(续)运行结果:(-0.8+6.2i)(3.8+2.8i)(0.9+3.4i)例6-2(续)6.1用函数实现对象的运算14“运算符重载”只能针对C++中原有运算符进行重载,不能通过重载创造出新的运算符。下列五个运算符不允许重载
. 成员访问运算符 .* 成员指针运算符 :: 作用域区分运算符 ?: 条件运算符 sizeof 测数据空间大小运算符
除此之外,C++的其他运算符都可以重载。
6.2运算符重载函数156.2运算符重载函数作为成员函数重载时,第一操作数就是当前对象本身,因此它并不需要出现在参数表中。除了new和delete以外,任何运算符都可以重载为成员函数,但不得重载为静态函数。=、[]、()、->以及所有的类型转换运算符只能作为成员函数重载。6.2.1运算符重载为成员函数例6-3:用“+”运算符实现复数的加法——重载“+”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput();//用于输出复数的函数 Complexoperator+(Complexc); //实现复数与复数相加的函数 Complexoperator+(doubler); //实现复数与实数相加的函数
};166.2运算符重载函数——6.2.1运算符重载为成员函数voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
ComplexComplex::operator+(Complexc){ returnComplex(real+c.real,image+c.image);}
ComplexComplex::operator+(doubler){ returnComplex(real+r,image);}176.2运算符重载函数——6.2.1运算符重载为成员函数例6-3(续)例6-3(续)intmain(){ Complexa(1.5,2.8),b(-2.3,3.4); Complexc1,c2; c1=a+b; c2=a+2.3; c1.output(); c2.output(); return0;}186.2运算符重载函数——6.2.1运算符重载为成员函数运行结果:(-0.8+6.2i)(3.8+2.8i)例6-3(续)6.2运算符重载函数——6.2.1运算符重载为成员函数206.2运算符重载函数运算符也可以重载为类的友元函数,由于友元函数不是任何类的成员函数,因此重载时必须在参数表中显式地给出所有的操作数。单目运算符“++”和“--”具有前置和后置两种形式。为了区分这两种形式,C++语法规定以成员函数形式重载的后置单目运算符要增加一个int类型的参数。6.2.2运算符重载为非成员函数例6-4:用“+”运算符实现复数的加法——重载“+”为友元函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput(); friendComplexoperator+(Complexc1,Complexc2); friendComplexoperator+(Complexc,doubler); friendComplexoperator+(doubler,Complexc);};216.2运算符重载函数——6.2.2运算符重载为非成员函数voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
Complexoperator+(Complexc1,Complexc2){ returnComplex(c1.real+c2.real,c1.image+c2.image);}
Complexoperator+(Complexc,doubler){ returnComplex(c.real+r,c.image);}
226.2运算符重载函数——6.2.2运算符重载为非成员函数例6-4(续)Complexoperator+(doubler,Complexc){ returnComplex(r+c.real,c.image);}intmain(){ Complexa(1.5,2.8),b(-2.3,3.4); Complexc1,c2,c3; c1=a+b; c2=a+2.3; c3=3.4+b; c1.output(); c2.output(); c3.output(); return0;}236.2运算符重载函数——6.2.2运算符重载为非成员函数例6-4(续)运行结果:(-0.8+6.2i)(3.8+2.8i)(1.1+3.4i)例6-4(续)6.2运算符重载函数——6.2.2运算符重载为非成员函数25运算符也可以重载为类的友元函数,由于友元函数不是任何类的成员函数,因此重载时必须在参数表中显式地给出所有的操作数。单目运算符“++”和“--”具有前置和后置两种形式。为了区分这两种形式,C++语法规定以成员函数形式重载的后置单目运算符要增加一个int类型的参数。6.3典型运算符的重载例6-5:“*”运算符实现复数的乘法
——重载“*”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput();//用于输出复数的函数 Complexoperator*(Complexc); //复数与复数相乘的函数 Complexoperator*(doubler); //复数与实数相乘的函数
};
266.3典型运算符的重载voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
ComplexComplex::operator*(Complexc){returnComplex(real*c.real-image*c.image,real*c.image+image*c.real);}
ComplexComplex::operator*(doubler){ returnComplex(real*r,image*r);}276.3典型运算符的重载例6-5(续)例6-5(续)intmain(){ Complexa(2.0,3.0),b(1.0,4.0); Complexc1,c2; c1=a*b; c2=a*2.0; c1.output(); c2.output(); return0;}286.3典型运算符的重载运行结果:(-10+11i)(4+6i)例6-5(续)6.3典型运算符的重载例6-6:“*”运算符实现复数的乘法
——重载“*”为友元函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput();//用于输出复数的函数 friendComplexoperator*(Complexc1,Complexc2); };
306.3典型运算符的重载例6-6(续)voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
Complexoperator*(Complexc1,Complexc2){ returnComplex(c1.real*c2.real-c1.image*c2.image,c1.real*c2.image+c2.image*c1.real);}
316.3典型运算符的重载例6-6(续)intmain(){ Complexa(2.0,3.0),b(1.0,4.0); Complexc; c=a*b; c.output(); return0;}326.3典型运算符的重载运行结果:(-10+11i)例6-6(续)6.3典型运算符的重载例6-7:用“-”运算符实现求复数的相反数——重载“-”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput();//用于输出复数的函数 Complexoperator-(); //复数取相反数的函数};346.3典型运算符的重载例6-7(续)voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
ComplexComplex::operator-(){ returnComplex(-real,-image);}356.3典型运算符的重载例6-7(续)intmain(){ Complexa(2.0,3.0); Complexc; c=-a; c.output(); return0;}366.3典型运算符的重载运行结果:(-2-3i)例6-7(续)6.3典型运算符的重载例6-8:用“-”运算符实现求复数的相反数——重载“-”为友元函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput();//用于输出复数的函数 friendComplexoperator-(Complexc);//复数取相反数的函数};386.3典型运算符的重载voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"<<endl; else cout<<"("<<real<<"+"<<image<<"i)"<<endl;}
Complexoperator-(Complexc){ returnComplex(-c.real,-c.image);}intmain(){ Complexa(2.0,3.0); Complexc; c=-a; c.output(); return0;}396.3典型运算符的重载例6-8(续)运行结果:(-2-3i)例6-8(续)6.3典型运算符的重载例6-9:用“==”运算符判断复数的相等——重载“==”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} booloperator==(Complexc); //判断两复数是否相等的函数};
boolComplex::operator==(Complexc){ returnreal==c.real&&image==c.image;}416.3典型运算符的重载例6-9(续)intmain(){ Complexa(2.0,3.0),b(2.0,3.0),c(3.0,2.0); cout<<"a==b:"<<(a==b)<<endl; cout<<"a==c:"<<(a==c)<<endl; return0;}426.3典型运算符的重载运行结果:a==b:1a==c:0例6-9(续)6.3典型运算符的重载例6-10:用“==”运算符判断复数的相等——重载“==”为友元函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} friendbooloperator==(Complexc1,Complexc2); };
booloperator==(Complexc1,Complexc2){ returnc1.real==c2.real&&c1.image==c2.image;}446.3典型运算符的重载例6-10(续)intmain(){ Complexa(2.0,3.0),b(2.0,3.0),c(3.0,2.0); cout<<"a==b:"<<(a==b)<<endl; cout<<"a==c:"<<(a==c)<<endl; return0;}456.3典型运算符的重载运行结果:a==b:1a==c:0例6-10(续)6.3典型运算符的重载例6-11:用“++”运算符实现复数的实部增1——重载“++”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput(); Complex&operator++(); //前置增1运算符函数 Complexoperator++(int); //后置增1运算符函数
};476.3典型运算符的重载voidComplex::output(){ if(image<0.0) cout<<"("<<real<<image<<"i)"; else cout<<"("<<real<<"+"<<image<<"i)";}
Complex&Complex::operator++(){ ++real; return*this; }
ComplexComplex::operator++(int){ returnComplex(real++,image);}486.3典型运算符的重载例6-11(续)intmain(){ Complexa(2.0,3.0),b(3.0,2.0); cout<<"++"; a.output(); ++a; cout<<"="; a.output(); cout<<endl; b.output(); cout<<"++"; b++; cout<<"="; b.output(); cout<<endl; return0;}496.3典型运算符的重载例6-11(续)运行结果:++(2+3i)=(3+3i)(3+2i)++=(4+2i)例6-11(续)6.3典型运算符的重载例6-12:用“++”运算符实现复数的实部增1——重载“++”为友元函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput(); friendComplex&operator++(Complex&c); friendComplexoperator++(Complex&c,int);};516.3典型运算符的重载例6-12(续)voidComplex::output(){ if(image<0.0) cout<<“(”<<real<<image<<“i)”; else cout<<“(”<<real<<“+”<<image<<“i)”;}
Complex&operator++(Complex&c){ ++c.real; returnc; }
Complexoperator++(Complex&c,int){ returnComplex(c.real++,c.image);}526.3典型运算符的重载例6-12(续)intmain(){ Complexa(2.0,3.0),b(3.0,2.0); cout<<“++”; a.output(); ++a; cout<<“=”; a.output(); cout<<endl; b.output(); cout<<“++”; b++; cout<<"="; b.output(); cout<<endl; return0;}536.3典型运算符的重载运行结果:++(2+3i)=(3+3i)(3+2i)++=(4+2i)例6-12(续)6.3典型运算符的重载例6-13:用“=”运算符实现复数的赋值——重载“++”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput(); Complex&operator=(constComplex&c); };556.3典型运算符的重载例6-13(续)voidComplex::output(){ if(image<0.0) cout<<“(”<<real<<image<<“i)”<<endl; else cout<<“(”<<real<<“+”<<image<<“i)”<<endl;}
Complex&Complex::operator=(constComplex&c){ real=c.real; image=c.image; return*this; }566.3典型运算符的重载例6-13(续)intmain(){ Complexa(2.0,3.0),b(3.0,2.0); cout<<“赋值前:a=”; a.output(); cout<<“赋值前:b=”; b.output(); cout<<“赋值表达式的值:”; (a=b).output(); cout<<“赋值后:a=”; a.output(); cout<<“赋值后:b=”; b.output(); return0;}576.3典型运算符的重载运行结果:赋值前:a=(2+3i)赋值前:b=(3+2i)赋值表达式的值:(3+2i)赋值前:a=(3+2i)赋值前:b=(3+2i)例6-13(续)6.3典型运算符的重载例6-14:为Student类重载基于深
层复制的赋值运算符
=//Student.h#include<iostream>#include<sstream>usingnamespacestd;classStudent{ char*name; //姓名 charthe_class[12]; //班号public: Student():name(NULL){the_class[0]=‘\0’;} Student(char*name,charthe_class[]); ~Student(){delete[]name;} constchar*getName()const{returnname;} constchar*getClass()const{returnthe_class;} voidtoUpper(){strupr(name);} stringtoString()const; //Student&operator=(constStudent&st); };596.3典型运算符的重载例6-14(续)Student::Student(char*name,charthe_class[]){ this->name=strdup(name); strcpy(this->the_class,the_class);}stringStudent::toString()const{ ostringstreamost; ost<<“Name:”<<name<<“Class:”<<the_class<<“ ”; returnost.str();}
606.3典型运算符的重载例6-14(续)/* Student&Student::operator=(constStudent&st){ //若参数与赋值的两个操作数是同一对象,不做任何处理 if(&st==this)return*this; //指针成员被覆盖前应释放所占用的资源 if(name!=NULL)delete[]name; //使指针成员指向一个新姓名的拷贝 name=strdup(); strcpy(the_class,st.the_class); //复制班号 return*this;}*/616.3典型运算符的重载例6-14(续)intmain(){ Studenta(“Jim”,“071103”),b(“Mary”,“051208”); cout<<“赋值前:”<<endl; cout<<a.toString()<<b.toString();//两个对象的初始状态 a=b; cout<<“赋值后:”<<endl; cout<<a.toString()<<b.toString();//赋值后的两个对象状态 a.toUpper(); cout<<“第一个学生的姓名改变为大写后:”<<endl; cout<<a.toString()<<b.toString(); return0;}626.3典型运算符的重载运行结果:赋值前:Name:JimClass:071103Name:MaryClass:051208赋值后:Name:MaryClass:051208Name:MaryClass:051208第一个学生的姓名改变为大写后:Name:MARYClass:051208Name:MARYClass:051208例6-14(续)6.3典型运算符的重载例6-15:用类型转换操作将复数转换为实数——重载“double”为成员函数#include<iostream>usingnamespacestd;classComplex{protected: doublereal; //复数的实部 doubleimage; //复数的虚部public: Complex(doubler=0.0,doublei=0.0){real=r;image=i;} voidoutput(); operatordouble(); //类型转换运算符函数};646.3典型运算符的重载例6-15(续)voidComplex::output(){ if(image<
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二手木屑削片机械购销合同合同
- 双良节能氢能技术应用合同协议
- 小学食品采购留样制度
- 公司采购制度模板
- 医疗器械采购规范制度范本
- 单位采购监督管理制度
- 冷链食品采购相关制度
- 水产采购制度
- 2025-2026学年陕西省西安市周至六中高二(上)期末政治试卷(含答案)
- 数字化转型下DT公司绩效管理体系的构建与实践研究
- 2024年4月全国自考00163管理心理学真题
- 鞋厂裁断生产管理报告
- 2022公共图书馆服务外包要求
- 2025年全国硕士研究生入学统一考试 (数学二) 真题及解析
- 2025新人教版七年级下册英语 Unit 6知识点梳理及语法讲义(答案版)
- 政策变化风险对市场营销的影响及应对策略
- 补办离婚委托书范本
- 第3章S7-300指令系统及编程
- 风雨同舟砥砺前行2025年度颁奖典礼
- 测绘项目安全保证措施
- 《广西壮族自治区 农田建设项目预算定额及概算编制规程》
评论
0/150
提交评论