2009-7-28 1
第 13章运算符重载
2009-7-28 2
运算符重载
C++中允许使用者重新定义已有的运算,使之能按用户规定的要求完成某些特定的操作,称 运算符重载 。
运用运算符重载可完成对象间的复杂操作,如加、
减法等。
重载运算符完成运算符重载的函数称为 运算符重载函数 。定义运算符重载函数的一般格式为:
类型 类名,:operator @(参数表 )
{…} //函数体关键字 重载运算符函数返回值的类型 运算符重载函数所在的类
2009-7-28 3
例 1,定义一个复数类,重载,+”和,-”运算符,使这两个运算符能直接完成复数的加法和减法运算。
1301执行后输出,Real=25 Image=50
Real=25 Image=50
Real=125 Image=250
Real=150 Image=300
Real=250 Image=500
注:
1,优先级和结合顺序不变
2,不能改变目数,单目无参数双目一个参数
3,重载函数名必须为 operator,后接一个合法的运算符
2009-7-28 4
+ - * / % ^ & |
~ !,= < > <= >=
++ - - << >> == != && ||
+= -= *= /= %= ^= &= |=
<<= >>= [ ] ( ) -> ->* new delete
4.C++中允许重载的运算符如下表:
2009-7-28 5
运算符 运算符的含义 不允许重载的原因
,三目运算符 在 C++中没有定义一个三目运算符的语法
,成员操作符 为保证成员操作符对成员访问的安全性,故不允许重载
* 成员指针操作符 同上
:,作用域操作符 因该操作符左边的操作数是一个类型名,而不是一个表达式
sizeof 求字节数操作符 其操作数是一个类型名,而不是一个表达式
5.C++中不允许重载的运算如下表:
2009-7-28 6
一元运算符的重载一元运算符重载的一般格式:
类型 类名,:operator 单目运算符()
{…} //函数体
“++”和,--”一元运算符存在前置与后置的问题。如对
,++”运算符。
,++”前置 时运算符重载函数的一般格式:
类型 类名,:operator ++()
{…} //函数体
,++”后置 时运算符重载函数的一般格式:
类型 类名,:operator ++( int)
{…} //函数体 没有实际意义,仅用作区分
“- -”运算符与,++”类似
2009-7-28 7
例 2,用一个类来描述人民币币值,用两个数据成员分别存放元和分。重载,++”运算符,实现对象的加 1
运算。
1302执行后输出:
25 50
25 51
25 51
105 70.9997
105 70.9997
1109元 97.3476分成员函数实现运算符重载时,
运算符的左操作符为当前对象
,并要用到隐含的指针 this。
运算符重载函数不能定义为静态的成员函数
2009-7-28 8
友元运算符两种实现运算符重载的方法:
用类的成员函数实现
用类的友元函数实现,称为 友元运算符 。
重载一元运算符的友元函数的一般格式:
friend 类型 operator @ (类名 X &对象名)
{…} //函数体运算符重载函数是类名 X的友元重载二元运算符的友元函数的一般格式:
friend 类型 operator @ (参数 1说明,参数 2说明)
{…} //函数体一元运算符二元运算符两个参数中至少有一个是类
X的对象
2009-7-28 9
例 3,用友元运算符实现复数的运算,包括二元运算符,+”、一元运算符,-”,用成员函数实现
,+=”运算。
1303执行后输出:
Real=25 Image=50
Real=25 Image=50
Real=125 Image=250
Real=150 Image=300
Real=250 Image=500
Real=450 Image=500
Real=-450 Image=-500
两种实现运算符重载的方法,用法相同,但编译器的处理不同。
2009-7-28 10
转换函数转换函数 (或称 类型转换函数 )是类中定义的一个成员函数。一般格式为:
类名,:operator 类型()
{…} //函数体要转换后的数据类型将对象内的成员数据转换成指定类型的数据例 4,定义一个类,类中包含元、角、分,要把这三个数变成一个等价的实数。
1304执行后输出:
s1=30.7 s2=120.55
s3=30.7 s4=120.55
s5=30.7 s6=30.7
2009-7-28 11
注:
转换函数只能是成员函数,不能是友元函数;
转换函数的操作数是对象;
转换函数可以被派生类继承,可被说明为虚函数;
一个类中可定义多个转换函数;
任一成员转换函数可用成员函数实现。
转换函数比一般成员函数简洁
2009-7-28 12
当对象的成员中使用了动态的数据类型时
,不能直接相互赋值赋值运算符和赋值运算符重载例 5,对象间的直接赋值导致程序的运行错误。
1305该例中类 A应增加如下的赋值运算符重载函数:
A & operator=(A &b){
if(ps)delete[ ]ps;
if(b.ps){
ps=new char[strlen(b.ps)+1];
strcpy(ps,b.ps);
}
else ps=0;
return *this;
}
2009-7-28 13
几个特殊运算符的重载
“++”和,--”运算符下面说明用友元函数重载运算符,++”的方法

用友元前置,++”运算符重载的一般格式:
frind 类型 operator ++(类名 &);要实现,++”运算的对象用友元后置,++”运算符重载的一般格式:
frind 类型 operator ++(类名 &,int);
第一个参数是要实现,++”
运算的对象,第二个参数用于区分后置运算
2009-7-28 14
例 6,用友元函数实现,++”运算符的重载。
1306
执行后输出:
x=25 y=50 z=100
x=26 y=51 z=101
x=2 y=3 z=4
x=29 y=55 z=106
其余几种不作介绍。
2009-7-28 15
字符串类将定义字符串类作为重载运算符的综合应用。
C++中提供的字符处理能力较弱,不能直接对字符串进行加法、减法、拼接、字符间的相互赋值等操作。
下例通过定义字符串类实现对字符串符的各种操作,
以使使用字符串与对一般数据的操作一样。
例 7,实现字符串直接操作的字符串类。
1311执行后输出:
C++程序设计
C++程序设计学生学习 C++程序设计学生学习
students study C++ programming!
2009-7-28 16
例 8,字符串操作演示程序。
1312
运行结果为,
C++程序设计学生学习
s2=学生学习学生学习 c++程序设计
p=++程序设计
2009-7-28 17
对象参与运算查看是否为用成员函数重载的运算符实现是否 试图将运算符作友元运算符是 实现否 试图将对象转换为其他类型的操作数进行运算否出错是实现
2009-7-28 18
本章小结
运算符重载的定义及一般格式;
一元运算符的重载;
友元运算符的重载;
特殊运算符的重载;
字符串类运算符的重载。