版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第四章运算符重载一、运算符重载的概念运算符重载的概念C++中的表达式由运算符和操作数按照规则构成。例如,算术运算符包括加“+”、减“-”、乘“*”、除“/”和取模“%”。如果不做特殊处理,则这些算术运算符通常只能用于对基本数据类型的常量或变量进行运算,而不能用于对象之间的运算。运算符重载,就是给已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时产生不同的行为。运算符重载的目的是使得C++中的运算符也能够用来操作对象。用于类运算的运算符通常都要重载。有两个运算符,系统提供了默认的重载版本:赋值运算符=和地址运算符&。➢对于=,系统默认重载为对象成员变量的复制。➢对于&,系统默认重载为返回任何类对象的地址。可重载的运算符不可重载的运算符和符号这个一定要记住,每年必考与其他函数一样,重载运算符有一个返回类型和一个参数列表。这样的函数称为运算符函数。运算符可以被重载为全局函数,也可以被重载为类的成员函数。声明为全局函数时,通常应是类的友元。故运算符函数是一种特殊的友元函数或成员函数重载运算符为类的成员函数#include<iostream>usingnamespacestd;//复数类,如:3+4i实数和虚数,做加减的时候,是实数跟实数加减,虚数跟虚数加减classmyComplex{
private:
//实数跟虚数
doublereal,imag;
public:
//构造函数
myComplex();
myComplex(doubler,doublei);
//成员函数
voidoutCom();
//成员函数,减法
myComplexoperator-(constmyComplex&c);
//友元函数,加法
friendmyComplexoperator+(constmyComplex&c1,constmyComplex&c2);};myComplex::myComplex(){
real=0;
imag=0;}myComplex::myComplex(doubler,doublei){
real=r;
imag=i;}voidmyComplex::outCom(){
cout<<"("<<real<<","<<imag<<")";}//减法myComplexmyComplex::operator-(constmyComplex&c){
returnmyComplex(this->real-c.real,this->imag-c.imag);}//加法,友元函数myComplexoperator+(constmyComplex&c1,constmyComplex&c2){
returnmyComplex(c1.real+c2.real,c1.imag+c2.imag);}intmain(){
myComplexc1(1,2),c2(3,4),res;
c1.outCom();
cout<<"operator+";
c2.outCom();
cout<<"=";
res=c1+c2;//对象可以做加法了
res.outCom();
cout<<endl;
c1.outCom();
cout<<"operator-";
c2.outCom();
cout<<"=";
res=c1-c2;//对象可以做减法了
res.outCom();
cout<<endl;
return0;}输出:(1,2)operator+(3,4)=(4,6)(1,2)operator-(3,4)=(-2,-2)重载运算符为友元函数#include<iostream>usingnamespacestd;classmyComplex{
private:
doublereal,imag;
public:
myComplex();
myComplex(doubler,doublei);
voidoutCom();
//友元函数
friendmyComplexoperator+(constmyComplex&c1,constmyComplex&c2);
friendmyComplexoperator-(constmyComplex&c1,constmyComplex&c2);
friendmyComplexoperator-(constmyComplex&c1,doubler);
friendmyComplexoperator-(doubler,constmyComplex&c1);};myComplex::myComplex(){
real=0;
imag=0;}myComplex::myComplex(doubler,doublei){
real=r;
imag=i;}voidmyComplex::outCom(){
cout<<"("<<real<<","<<imag<<")";}myComplexoperator+(constmyComplex&c1,constmyComplex&c2){
//返回一个临时对象,c1+c2
returnmyComplex(c1.real+c2.real,c1.imag+c2.imag);}myComplexoperator-(constmyComplex&c1,constmyComplex&c2){
//返回一个临时对象,c1-c2新增
returnmyComplex(c1.real-c2.real,c1.imag-c2.imag);}myComplexoperator-(constmyComplex&c1,doubler){
//返回一个临时对象,c1-r新增
returnmyComplex(c1.real-r,c1.imag);}myComplexoperator-(doubler,constmyComplex&c1){
//返回一个临时对象,r-c1新增
returnmyComplex(r-c1.real,-c1.imag);}intmain(){
myComplexc1(1,2),c2(3,4),res;
c1.outCom();
cout<<"operator+";
c2.outCom();
cout<<"=";
res=c1+c2;
res.outCom();
cout<<endl;
res=c1-5;
res.outCom();
res=5-c1;
res.outCom();
return0;}输出:(1,2)operator+(3,4)=(4,6)(-4,2)(4,-2)重载运算符的规则1)重载后运算符的含义应该符合原有的用法习惯。例如,重载“+”运算符,完成的功能就应该类似于做加法,在重载的“+”运算符中做减法是不合适的。2)运算符重载不能改变运算符原有的语义,包括运算符的优先级和结合性。3)运算符重载不能改变运算符操作数的个数及语法结构。4)不能创建新的运算符,即重载运算符不能超出C++语言允许重载的运算符范围。5)重载运算符
()
[]
->
=时,只能将它们重载为成员函数,不能重载为全局函数。6)运算符重载不能改变该运算符用于基本数据类型对象的含义。真题逻辑运算符两侧运算对象的数据(D)。A:是逻辑型数据B:只能是整型数据C:只能是整型或字符型数据D:可以是任何类型的数据
注:在逻辑运算中,0为假,非0为真,一般用数字1表示设x和y均为bool量,则x&&y为真的条件是(A)。A:它们均为真B:其中一个为真C:它们均为假D:其中一个为假若要对Data类中重载的加法运算符成员函数进行声明,下列选项中正确的是(B)A:Data+(Data);B:Dataoperator+(Data);C:Data+operator(Data);D:operator+(Data,Data);以下程序段中与语句k=a>b?1:0;功能等价的是(A)。A:if(a>b)k=1;elsek=0;B:if(a>b)k=0;C:if(a<b)k=0;elsek=1;D:if(a>b)k=1预处理命令在程序中开头的符号是(B)。A:*B:#C:&D:@
下列运算符不能重载的是(B)。A:!B:sizeofC:newD:delete友元运算符@obj被C++编译器解释为(A)。A:operator@(obj)B:operator@(obj,0)C:obj.operator@()D:obj.operator@(0)下列关于运算符重载的表述中,正确的是(C)。A:C++已有的任何运算符都可以重载B:运算符函数的返回类型不能声明为基本数据类型C:在类型转换符函数的定义中不需要声明返回类型D:可以通过运算符重载来创建C++中原来没有的运算符下列关于运算符重载的叙述,正确的是(B)。A:通过运算符重载,可以定义新的运算符B:有的运算符只能作为成员函数重载C:若重载运算符+,则相应的运算符函数名是+
应该是:operator+D:重载一个二元运算符时,必须声明两个形参
如果是友元才是2个形参如果表达式++a中的“++”是作为成员函数重载的运算符,若采用运算符函数调用格式,则可表示为(D)A:a.operator++(1)
a++B:operator++(a)
++aC:operator++(a,1)
a++D:a.operator++()
++a
直接加1的就不需要参数,省事一点,a++是先赋值再加1,复杂一点,故参数也复杂一点,多1个参数设有类A的对象Aobject,若用成员函数重载前置自增运算符,则++Aobject被编译器解释为(A)A:Aobject.operator++()B:operator++(Aobject)C:++(Aobject)D:Aobject::operator++()以下关于运算符重载的描述中,错误的是(D)。A:运算符重载其实就是函数重载B:成员运算符比友元运算符少一个参数C:需要使用关键字operatorD:成员运算符比友元运算符多一个参数二、重载赋值运算符C++中的赋值运算符“=”要求左右两个操作数的类型是匹配的,或至少是赋值兼容的。有时希望“=”两边的操作数的类型即使不赋值兼容也能够成立,这就需要对“=”进行重载。C++规定,“=”只能重载为成员函数。若有类CL的两个对象s1和s2,则它们之间的赋值语句通常是下面这样的形式:s1=s2;当类CL中定义了成员函数,重载了赋值运算符后,上述赋值语句将解释为函数调用的形式:s1.operator=(s2);myComplex&myComplex::operator=(constmyComplex&c1)
//这里用&完全是为了效率{
this->real=c1.real;
this->imag=c1.imag;
return*this;}myComplex&myComplex::operator=(doubler){
this->real=r;
this->imag=0;
return*this;}intmain(){
myComplexc1(1,2),c2(3,4),res;
res=c1;}浅拷贝和深拷贝平时我们用到的=都是浅拷贝,如:a=5;如果是比较麻烦的像对象=的操作,把指针所指的地方赋值过去的叫深拷贝。浅拷贝:同类对象之间可以通过赋值运算符“=”互相赋值。如果没有经过重载,“=”的作用就是将赋值号右侧对象的值一一赋值给左侧的对象。这相当于值的拷贝,称为“浅拷贝”。深拷贝:重载赋值运算符后,赋值语句的功能是将一个对象中指针成员变量指向的内容复制到另一个对象中指针成员变量指向的地方,这样的拷贝叫“深拷贝”。浅拷贝示例地址不一样,只赋值了#include<iostream>usingnamespacestd;classpointer{
public:
inta;
int*p;
pointer(){
a=100;
p=newint(10);
}
pointer(constpointer&tempp){
if(this!=&tempp){
a=tempp.a;
p=tempp.p;
}
}};intmain(){
pointerp1;
pointerp2(p1);
pointerp3=p1;
cout<<"\n初始化后,各对象的值及内存地址"<<endl;
cout<<"对象名\t对象地址a的值p中的值p指向的值p的地址"<<endl;
cout<<"p1:\t"<<&p1<<","<<p1.a<<","<<p1.p<<","<<*p1.p<<","<<&p1.p<<endl;
cout<<"p2:\t"<<&p2<<","<<p2.a<<","<<p2.p<<","<<*p2.p<<","<<&p2.p<<endl;
cout<<"p3:\t"<<&p3<<","<<p3.a<<","<<p3.p<<","<<*p3.p<<","<<&p3.p<<endl;
*p1.p=20;
p2.a=300;
cout<<"\n修改后,各对象的值及内存地址"<<endl;
cout<<"对象名\t对象地址a的值p中的值p指向的值p的地址"<<endl;
cout<<"p1:\t"<<&p1<<","<<p1.a<<","<<p1.p<<","<<*p1.p<<","<<&p1.p<<endl;
cout<<"p2:\t"<<&p2<<","<<p2.a<<","<<p2.p<<","<<*p2.p<<","<<&p2.p<<endl;
cout<<"p3:\t"<<&p3<<","<<p3.a<<","<<p3.p<<","<<*p3.p<<","<<&p3.p<<endl;
return0;}初始化后,各对象的值及内存地址对象名
对象地址
a的值p中的值
p指向的值p的地址p1:
0x7ffe5ef41ac0,100,0x1316e70,10,0x7ffe5ef41ac8p2:
0x7ffe5ef41ab0,100,0x1316e70,10,0x7ffe5ef41ab8p3:
0x7ffe5ef41aa0,100,0x1316e70,10,0x7ffe5ef41aa8修改后,各对象的值及内存地址对象名
对象地址
a的值p中的值
p指向的值p的地址p1:
0x7ffe5ef41ac0,100,0x1316e70,20,0x7ffe5ef41ac8p2:
0x7ffe5ef41ab0,300,0x1316e70,20,0x7ffe5ef41ab8p3:
0x7ffe5ef41aa0,100,0x1316e70,20,0x7ffe5ef41aa8三、重载流插入运算符和流提取运算符在C++中,左移运算符“<<”可以和cout一起用于输出,故常被称为“流插入运算符”。右移运算符“>>”和cin—起用于输入,一般被称为流提取运算符。它们都是C++类库中提供的。在类库提供的头文件中已经对“<<”和“>>”进行了重载,使之分别作为流插入运算符和流提取运算符,能用来输出和输入C++基本数据类型的数据。cout是ostream类的对象,cin是istream类的对象,它们都是在头文件iostream中声明的。因此,凡是用“cout<<”和“cin>>”对基本数据类型数据进行输出/输入的,都要用#include指令把头文件iostream包含到本程序文件中。流插运算符必须重载为类的友元#include<iostream>usingnamespacestd;classtest{
private:
inti;
floatf;
charch;
public:
test(inta=0,floatb=0,charc='\0'){i=a;f=b;ch=c;}
friendostream&operator<<(ostream&,test);
friendistream&operator>>(istream&,test&);};ostream&operator<<(ostream&stream,testobj){
//stream是cout的别名
stream<<obj.i<<",";
stream<<obj.f<<",";
stream<<obj.ch<<endl;
returnstream;}istream&operator>>(istream&t_stream,test&obj){
//t_stream是cin的别名
t_stream>>obj.i;
t_stream>>obj.f;
t_stream>>obj.ch;
returnt_stream;}intmain(){
testA(45,8.5,'E');
operator<<(cout,A);
testB,C;
cout<<"Inputasifch:";
operator>>(cin,B);operator>>(cin,C);
operator<<(cout,B);operator<<(cout,C);}输出:45,8.5,WInputasifch:55.8A23.4a5,5.8,A2,3.4,a四、*重载强制类型转换运算符在C++中,类型的名字(包括类的名字)本身也是一种运算符,即强制类型转换运算符。强制类型转换运算符是单目运算符,也可以被重载,但只能重载为成员函数,不能重载为全局函数。经过适当重载后,“(类型名)对象”这个对对象进行强制类型转换的表达式就等价于“对象.operator类型名()”,即变成对运算符函数的调用。#include<iostream>usingnamespacestd;classmyComplex{
doublereal,imag;
public:
myComplex(doubler=0,doublei=0):real(r),imag(i){};
//重载强制类型转换运算符double
operatordouble(){
returnreal;
}};intmain(){
myComplexc(1.2,-3.4);
cout<<(double)c<<endl;//输出1.2
doublen=12+c;
//等价于:doublen=12+c.operatordouble();
或doublen=12+(double)c;
cout<<n;//输出:13.2
return0;}五、重载自增、自减运算符自增运算符“++”和自减运算符“--”都可以被重载,但是它们有前置和后置之分。以“++”为例,对于整数k,“++k”和“k++”的语义是不一样的。当“++”用于对象时,也应该如此。例如,obj是一个类CDemo的对象,那么“++obj”和“obj++”的含义应该是不一样的。按照自增运算符及自减运算符的本来定义,“++obj”的返回值应该是obj被修改后的值,而“obj++”的返回值应该是obj被修改前的值#include<iostream>usingnamespacestd;classCDemo{
private:
intn;
public:
CDemo(inti=0):n(i){}
CDemo&operator++();//用于前置形式
CDemooperator++(int);//用于后置形式,a++会多一个参数,因为先赋值再加1比较费劲
operatorint(){//重载强制转换符
returnn;
}
friendCDemo&operator--(CDemo&);//友元函数
friendCDemooperator--(CDemo&,int);
//CDemo&operator--();如果用成员函数
//CDemooperator--(int);};//前置++CDemo&CDemo::operator++()
{
n++;
return*this;}//后置++,多一个参数CDemoCDemo::operator++(intk)
{
CDemotmp(*this);//记录修改前的对象
n++;
returntmp;//返回修改前的对象}//前置--CDemo&operator--(CDemo&d)
{
d.n--;
returnd;}
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度服务合同范例concerning标的:市场调研服务5篇
- 二零二五年度石灰产品仓储物流合同范本3篇
- 二零二五年度物流园区运营补充协议合同范本3篇
- 二零二五年度社区儿童福利院抚养服务合同
- 二零二五年度水利工程委托设计合同范本6篇
- 2024年版:股份代持与表决权委托合同
- 二零二五年度沥青混凝土搅拌站运营合同3篇
- 二年级班主任期中工作总结引导学生积极参与
- 五年级班主任的教育心得与工作总结
- 二零二五年度智能家居智能家居住宅装修合同违约责任合同3篇
- 出现产品质量问题退换货承诺
- 合伙开托管班协议书4篇
- 广告宣传物料广告宣传物料配送方案
- 2024年长春医学高等专科学校单招职业适应性测试题库及答案解析
- 项目维修维保方案
- 上海市浦东新区2023-2024学年一年级上学期期末考试数学试题
- 前列腺增生药物治疗
- 足球教练员管理制度模版
- IQC来料检验记录表
- 滴滴补贴方案
- 成长生涯发展展示
评论
0/150
提交评论