第4章运算符重载2
vc 04 运算符重载

于是: 于是:
string x,y; x=x+y; //表示串 和串 合并,放入串 表示串x 表示串 和串y 合并,放入串x
这就使对基本类型的预定义运算符" 的含义在串类中被扩展 这就使对基本类型的预定义运算符"+"的含义在串类中被扩展 为对串类对象的合并操作,即运算符"+"被重载. 为对串类对象的合并操作,即运算符" 被重载. 被重载 运算符重载应注意的几个问题: 运算符重载应注意的几个问题: 1,哪些运算符可以重载? 哪些运算符可以重载? 中除了下面四种运算符外, 在C++ 中除了下面四种运算符外,系统预定义的运算符都 能被重载. 能被重载.
string x,y;
那么, 实现两个串的合并. 那么,可以使用函数strcat(x,y)实现两个串的合并. 如果在表示字符串的类对象x, 的特定环境下,运算符" 使 如果在表示字符串的类对象 ,y 的特定环境下,运算符"+"使 用于类对象,能被解释为串对象x 的合并, 用于类对象,能被解释为串对象 和y 的合并,则编程就更方便 了.
例如:下边是运算符重载的另一个例子,程序实现了复数的加 例如:下边是运算符重载的另一个例子, 和减运算. 和减运算.
#include <iostream.h> class Complex { public: Complex() { real=imag=0.0; } Complex(double r) { real=r; imag=0.0; } Complex(double r,double i) { real=r; imag=i; } Complex operator+(const Complex& c); Complex operator-(const Complex& c); friend void print(const Complex& c); private: double real,imag; };
实验9 运算符重载(2)

实验9 运算符重载(1)一、实验目的1、掌握运算符重载的概念;二、实验内容1、用成员函数重载运算符,使对整型的运算符=、+、-、*、/ 适用于分数运算。
要求:(1)输出结果是最简分数(可以是带分数);(2)分母为1,只输出分子。
过程分析:1) 定义一个类Complex,在公共部分定义构造函数,输出函数,和运算符=、+、-、*、/的重载函数,此处运算符=可以使用系统默认的运算符=的函数。
在私有部分定义两个数据成员x和y。
2) 定义构造函数时先在类里面声明构造函数,并对参数初始化,再在类外定义构造函数,分别给x和y初始化。
3) 定义输出函数print(),对分数进行化简,采用的方法是利用for循环,分子分母均除以i,i从2增加到分子分母中更小的一个数后截止,每次增加1,在利用if else 语句,如果分子分母除以i均被整除,则说明这是的i是分子分母的公约数,分子分母均赋值为整除后的结果值,同时将i重新赋值为2,因为再求公约数是要再从i=2开始循环;否则i++,表示及进入下一个循环。
化成最简形式后在利用if else语句,判断最终结果值的分母是否为1,如果不是,则输出分数,否则只输出分子。
4) 定义运算符+重载函数,参数作为+的右操作对象,调用函数的对象作为左操作对象,在函数里定义一个Complex对象d,将左右操作对象的分数相加,将得到的结果的分子和分母分别赋给d的分子和分母,返回类的对象d。
5) 定义运算符-重载函数,参数作为-的右操作对象,调用函数的对象作为左操作对象,在函数里定义一个Complex对象d,将左右操作对象的分数相减,并将得到的结果的分子和分母分别赋给d的分子和分母,返回类的对象d。
6) 定义运算符*重载函数,参数作为*的右操作对象,调用函数的对象作为左操作对象,在函数里定义一个Complex对象d,将左右操作对象的分数相乘,并将得到的结果的分子和分母分别赋给d的分子和分母,返回类的对象d。
4第四章 运算符重载

const complex operator - (const complex &c) const; void display(); //输出复数 private: //私有数据成员 1.是为了堵塞a+b=c的漏洞。 double real; //复数实部 2. 3.是为了扩大适应性。 double imag; //复数虚部 };
17
[ ]运算符重载为成员函数
下标运算符[]可以重载: 重载形式为:operator[](int); 当 X x; 隐含调用。 x[y] 可被解释为: 显式调用。 x. operator [ ](y); 只能重载为成员函数,不能使用友元函数。 这个类显然是个‚数组类‛。
18
前置++和后置++重载为成员函数
9
使用
void main(){
complex c1(5,4),c2(2,10),c3; //三个复数类的对象 cout<<"c1="; cout<<"c2="; c1.display(); c2.display();
c3=c1-c2; //使用重载运算符完成复数减法 cout<<"c3=c1-c2="; c3.display(); 程序输出结果为:
这三个运算符是许多 教课书没有提到的。
唯一的一个三目运 算符不能重载。
3
运算符重载的基础
设计运算符重载函数,首先要了解运算符原本的运算语义。重
载函数要忠实遵守该运算符作用于基本数据类型时的语义,
并表现出自身所特有的性质。 例如:+ 、+= 、=、++(前)、++(后) ....
简述运算符重载的规则

简述运算符重载的规则
运算符重载可以用来定义自定义类型的操作行为。
以下是运算符重载的规则:
1. 运算符重载函数必须是类或枚举类型的成员函数或全局函数。
2. 运算符重载函数的名称必须是“operator”加上要重载的运算符符号,例如“operator +”或“operator <<”。
3. 运算符重载函数必须指定参数列表,包括参数类型和数量,不能有默认值。
4. 运算符重载函数可以返回任何类型,但不能返回void 类型。
5. 运算符重载函数可以是const 成员函数,如果不会修改对象的状态。
6. 运算符重载函数可以被重载多次,只要参数列表不同。
7. 运算符重载函数不能改变运算符的优先级和结合性,也不能改变运算符的语法。
8. 运算符重载应该符合语义上的期望,例如“+”操作符应该执行加法,而不是减法。
9. 运算符重载应该遵循刚才提到的运算符的语法和行为。
总之,运算符重载在正确地使用时,可以使代码更加直观,易于理解,也可以让自定义数据类型具有更多的功能和操作。
运算符重载

1、多态性的基本概念2、派生类对象替换基类对象3、虚函数的定义4、抽象类的定义5、宠物类的设计6、运算符重载7、日期类对象判断大小8、分数类对象运算符重载☐运算符重载指赋予运算符新的操作功能,主要用于对类的对象的操作☐运算符+意味着多少对象类型的加法呢?☐还可以定义新的对象类型加法☐运算符重载定义形式:<类型><类名>::operator<操作符>(<参数表>){函数体}☐首先定义虚数类☐虚数可以描述为:a+bi☐a与b看成实数,定义成double类型☐成员函数除了构造与析构外,还有:☐输出虚数、修改虚数、得到实部a、得到虚部b ☐相加+、判相等==#include <iostream>using namespace std;class Complex{private:double real, imag;public:Complex(double r = 0, double i = 0): real(r), imag(i){ }double Real(){return real;}double Imag(){return imag;}Complex operator +(Complex&);Complex operator +(double);bool operator ==(Complex);~Complex(){ };Complex Complex::operator +(Complex &c)// 重载运算符+,两边是虚数对象{Complex temp;temp.real = real+c.real;temp.imag = imag+c.imag;return temp;}Complex Complex::operator +(double d)// 重载运算符+,左边是虚数对象,右边是双精度数{Complex temp;temp.real = real+d;temp.imag=imag;return temp;}bool Complex::operator ==(Complex c)// 重载运算符=={if (real == c.real && imag == c.imag)return true;elseint main(){Complex c1(3,4),c2(5,6),c3;cout << "C1 = " << c1.Real() << "+j" << c1.Imag() << endl;cout << "C2 = " << c2.Real() << "+j" << c2.Imag() << endl;c3 = c1+c2;cout << "C3 = " << c3.Real() << "+j" << c3.Imag() << endl;c3 = c3+6.5;cout << "C3 + 6.5 = " << c3.Real() << "+j" << c3.Imag() << endl;if ( c1==c2 )cout<<“两个复数相等”;elsecout<<“两个复数不相等”;return 0;☐运算符++分前置运算符和后置运算符☐例如: ++Y与Y++☐前置运算符定义Complex Complex::operator ++ () {real+=1;return *this;}☐后置运算符定义Complex Complex::operator ++ (int) {real+=1;return *this;}。
第4章 运算符重载

• 在C++中只能重载单目运算符、双目运算符及 不确定目数运算符“()”
下列运算符不能重载 . 类成员运算符 .* 成员指针运算符 :: 域解析运算符 ?: 条件表达式运算符 “#” (???) sizeof(???)
重载运算符有哪些限制?
(1) 不可臆造新的运算符。必须把重载运算符 限制在C++语言中已有的运算符范围内的允许 重载的运算符之中。 (2) 重载运算符坚持4个“不能改变”。 · 不能改变运算符操作数的个数; · 不能改变运算符原有的优先级; · 不能改变运算符原有的结合性; · 不能改变运算符原有的语法结构
用类的成员函数重载双目运算符
• 双目运算符重载为类的成员函数时,形参 表中有一个参数,以当前对象作为运算符 的左操作数,参数作为右操作数。
例4.4 双目运算符重载为类的成员函数示例。 // 声明整型类 class Integer { private: // 数据成员 int num; // 数据值 public: // 公有函数 Integer(int n = 0): num(n){ } // 构造函数 void Set(int n) { num = n; } // 设置数据值 int Get() const { return num; } // 返回数据值 Integer operator+(const Integer &a) const// 重载加法运算符“+” { return Integer(this->num + a.num); } }; int main() // 主函数main() { Integer i(6), j(9), k; // 定义整型对象 k = i + j; // 对整型对象求加法运算,i+j等价于i.operator+(j); cout<<i.Get()<<"+"<<j.Get()<<"="<<k.Get()<<endl;// 输出数值 system("PAUSE"); // 输出系统提示信息 程序运行时屏幕输出如下: return 0; // 返回值0, 返回操作系统 6+9=15 } 请按任意键继续. . .
运算符重载

24
运算符重载
思考:如果希望表达式i+c1有意义, 思考:如果希望表达式i+c1有意义,应该 i+c1有意义 如何定义重载运算符函数? 如何定义重载运算符函数?
friend Complex operator+(int &i,Complex &c); Complex operator+(int &i, Complex &c) {return Complex(i+c.real,c.imag);}
2
什么是运算符重载
代码分析: 代码分析: 例10.1 通过函数来实现复数 相加。 相加。
CCS E
3
运算符重载的方法
运算符重载的方法是定义一个重载运 算符的函数, 算符的函数,在需要执行被重载的运 算符时,系统就自动调用该函数, 算符时,系统就自动调用该函数,以 实现相应的运算。也就是说, 实现相应的运算。也就是说,运算符 重载是通过定义函数实现的。 重载是通过定义函数实现的。运算符 重载实质上是函数的重载。 重载实质上是函数的重载。
CCS E
21
运算符重载
如果将运算符重载函数作为成员函数, 如果将运算符重载函数作为成员函数, 它可以通过this this指针自由地访问本类 它可以通过this指针自由地访问本类 的数据成员, 的数据成员,因此可以少写一个函数 的参数。 的参数。但必须要求运算表达式第一 个参数(即运算符左侧的操作数) 个参数(即运算符左侧的操作数)是一 个类对象, 个类对象,而且与运算符函数的类型 相同。 相同。因为必须通过类的对象去调用 该类的成员函数,而且只有运算符重 该类的成员函数, 载函数返回值与该对象同类型, 载函数返回值与该对象同类型,运算 结果才有意义。 结果才有意义。
4 运算符重载

可以将+代表的操作看成一个函数:+为函数的名字,+操作的两个操 作数的类型即为函数形参的类型,+操作的结果的类型即为函数的返回 值类型。
北京化工大学 VC++ 教学课件
2
计算机系 江志英 jiangzy@
运算符重载的提出
C/C++中,每种基本数据类型的变量都可通过几种运算符来做相关计 算,如int型变量,它们可以同“+”,“-”,“*”,“/”等运算符 来做加法,减法,乘法,除法等。如:
4 5 6
常用运算符的重载
重载赋值运算符operator=
重载输入/输出运算符 << | >>
重载下标运算符operator[ ]
重载类型转换函数
北京化工大学 VC++ 教学课件
4
计算机系 江志英 jiangzy@
运算符重载的基本语法
运算符的使用和普通函数在语法上有所不同,但是可以将 运算符看作是一种特殊的函数,操作数是函数的参数,运 算结果是函数的返回值。
北京化工大学 VC++ 教学课件
14
计算机系 江志英 jiangzy@
// 重载运算符的使用示例 int main() { Byte a, b, *bp; +b; -b; ~b; bp = &b; !b; ++b; b++; --b; b--; } //end of main()
3
Vector vec1,vec2 vec1+vec2; vec1-vec2; vec1*vec2; vec1/vec2; 两个向量类对象的加减乘除
C++提供了运算符重载机制来帮助我们实现上述目的。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在类体中,可以有转换构造函数,也可以没有 转换构造函数,视需要而定。
u{ sing namespace std;
crloeautsutsprnuCtCo<mo<m“p(“lpe<lxe<xc(.real+<c<2“+.r”e<a<l,cim.imaaggee+<c2<.“im”<a<geen)d; l;
}{rpeutubrlinc:output;
ቤተ መጻሕፍቲ ባይዱ
}coCuinott<mm<p“al(ei“nx<(()<){cre3a.rle=a0l;<im<a“+g=”<0<;}c3.image<<“i”<<endl;
第1页 共28页
目录
目退录出
4.7 重载流插入运算符和流提取运算符
➢ 只能将重载“<<” 和“>>” 的函数作为友 元函数或普通的函数,而不能将它们定义为 成员函数。
➢ 例4.7 在例4.2的基础上,用重载的“<<”输 出复数。
第2页 共28页
目录
目退录出
#Coisontmcrelupadlmeex&<Coioopsmetrpealaetomxr:>:<o<pe(orasttorer a+m(C&oomutppleuxt,C&ocm2)plex& c)
<< >>
(ostream&,Complex&); (istream&, Complex&);
docuinb>le>cre1a>l>;c2;
docuobulte<<im“ca1=g”;<<c1;
}; cout<<“c2=”在<<执c2;行本句时,调用:
return 0; }
operator>>(cin,c1)
4.8 不同类型数据间的转换
C++还提供显式类型转换,程序人员在 程序中指定将一种指定的数据转换成另 一指定的类型,其形式为 :
类型名(数据) 如 int(89.5) 其作用是将89.5转换为整型数89。
第7页 共28页
目录
目退录出
4.8 不同类型数据间的转换
➢ 对于用户自己声明的类型,编译系统并不知 道怎样进行转换。解决这个问题的关键是让 编译系统知道怎样去进行这些转换,需要定 义专门的函数来处理。
coclaousutpst<uC<t<“o<“m“in(“pp<lu<etcxr.ereaal la<;n<d“+im”<a<gci.nimaraygpea<r<t “oi”f<c<oemnpdle; x number:”;
{}}}opprirrnfueeerffu(rripctttvbiipuuueeu.i{aiulcnrrrmtinnnnn>tcittCn<edda>:mioo>o<n:gcuuoi>mapcse.ttrsc.iuppt>pnier1mttuu=l(era;e.)ettr0ala;;x>eag)m>acemolc1><&u.&,i><tcmpc“2ouoia1”;tp<pg.<ie<eme<er;r“aaa+ngttd”ooe;l;r;r
第5页 共28页
目录
目退录出
4.8 不同类型数据间的转换
➢ 4.8.1 标准类型数据间的转换 在C++中,某些不同类型数据之间可以自动转 换,例如 int i = 6; i = 7.5 + i; 这种转换是由C++编译系统自动完成的,用户 不需干预。这种转换称为隐式类型转换。
第6页 共28页
目录
目退录出
第8页 共28页
目录
目退录出
4.8 不同类型数据间的转换
➢ 4.8.2 转换构造函数 转换构造函数(conversion constructor function) 的作用是将一个其他类型的数据转 换成一个类的对象。
第9页 共28页
目录
目退录出
4.8 不同类型数据间的转换
先回顾一下以前学习过的几种构造函数: 默认构造函数: Complex( ); //没有参数 用于初始化的构造函数: Complex(double r,double i); 用于复制对象的复制构造函数: Complex (Complex &c);
第10页 共28页
目录
目退录出
一种新的构造函数——转换构造函数
转换构造函数只有一个形参,如 Complex(double r) {real=r;imag=0;}
其作用是将double型的参数r转换成Complex 类的对象,将r作为复数的实部,虚部为0。
第11页 共28页
目录
目退录出
一种新的构造函数——转换构造函数
privactoeu: t<<c3;
}; }ddooruuebbtulleernrime0a;alg; ;在执o行per本ato句r<时<(c,ou系t,c统3) 把它解释为:
第3页 共28页
目录
目退录出
4.7 重载流插入运算符和流提取运算符
➢ 4.7.2 重载流提取运算符“>>” ➢ 例4.8 在例4.7的基础上,增加重载流提取运
C{ omplex(double r,double i){real=r;imag=i;}
CoCmopmlepxleoxpce1ra(2to,4r )+,c(2C(6o,m10p)le,cx3&; c2);
friecn3d=co1s+trce2a;m& operator <<(ostream&,Complex&);
算符“>>”,用“cin”输入复数,用 “<<” 输出复数。
第4页 共28页
目录
目退录出
#oissitnrtrecealaummd&e&o<oppieoersraattroteorar>m<><>((isotsretraemam&&inoputp,Cuto,Cmopmlepxl&exc&) c)
u{ sing namespace std;
4.7 重载流插入运算符和流提取运算符
➢ 4.7.1 重载流插入运算符“<<” 用户自己定义的类型的数据,是不能直接用
“<<” 和“>>”来输出和输入的。如果想用 它们输出和输入自己声明的类型的数据,必 须对它们重载。
➢ 对“<<” 和“>>”重载的函数形式如下:
➢ istream & operateor >> (istream &,自定义类); ➢ ostream & operateor >> (ostream &,自定义类);