1、第21次课运算符重载第21讲教学内容8.1 多态性概述 8.1.1多态的类型 8.1.2 多态的实现8.2 运算符重载 8.2.1 运算符重载的规则 8.2.2 运算符重载为成员函数 8.2.3 运算符重载为友元函数 教学重点和难点1多态的理解2 运算符重载的作用3 运算符重载的两种形式,了解如何重新定义(重载)运算符以处理新的抽象数据类型教学方法:通过举现实生活中的例子,讲解多态的概念。通过程序举例演示,讲解运算符重载的作用,运算符重载的两种形式 教学学时2 学时教学过程一 多态 :1 多态性是面向对象程序设计的重要特征之一。2多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同
2、的行为。3多态的实现:函数重载运算符重载虚函数二运算符重载:1运算符重载的实质1)如何将C+中的运算符和类对象结合一起使用,这个过程称为运算符重载(operator voerlonding)。C+允许程序员重载大多数运算符,使其更符合使用场景,编辑器根据运算符的使用方式生成合适的代码。虽然重载运算符的实现的也可以通过显示函数调用来完成,但是使用重载运算符可以使程序更清晰,针对同样的操作,使用运算符重载比使用显式函数调用更能提高程序的可读性。对于类对象的运算符必须重载,但赋值运算符(=)无须显式重载就可以用语每个类,其默认行为是类数据成员的逐个赋值,但这种默认行为对带有指针成员的类是危险的,此时
3、可以显式重载赋值运算符。2)运算符重载是对已有的运算符赋予多重含义3)必要性C+中预定义的运算符其运算对象只能是基本数据类型,而不适用于用户自定义类型(如类)4)实现机制将指定的运算表达式转化为对运算符函数的调用,运算对象转化为运算符函数的实参。编译系统对重载运算符的选择,遵循函数重载的选择原则。2运算符重载的规则和限制:1)可以重载C+中除下列运算符外的所有运算符:. .* : ?:2)只能重载C+语言中已有的运算符,不可臆造新的。3)不改变原运算符的优先级和结合性。重载运算符应该模拟其内部对象的功能。例如:+运算符重载后,应该仍然执行加法运算,而不是减法运算。4)不能改变操作数个数。5)经
4、重载的运算符,其操作数中至少应该有一个是自定义类型。(运算符重载不能改变该运算符用于内部类型对象时的作用方式)三 运算符重载的两种形式:C+为其内部类型提供了丰富的运算符集,重载这些运算符的目的是为用户自定义的类型提供同样简洁的表达式,但运算符的重载不是自动完成的,程序员必须为所要执行的操作编写运算符函数,有时候把这些函数用作成员函数,有时最好用作友元函数,在极少数情况下,他们可能既不是成员函数,也不是友元函数。1重载为成员函数:当运算符函数作为成员函数实现时,最左边的操作数必须是运算符类的一个类对象(或者是该类对象的一个引用)。例如重载运算符(),-或者任何赋值运算符时,运算符函数必须声明为
5、类的一个成员函数。1)声明形式函数类型 operator 运算符(形参)2)重载为类成员函数时 参数个数=原操作数个数-1 (后置+、-除外)3)双目运算符 B如果要重载 B 为类成员函数,使之能够实现表达式 oprd1 B oprd2,其中 oprd1 为A 类对象,则 B 应被重载为 A 类的成员函数,形参类型应该是 oprd2 所属的类型。经重载后,表达式 oprd1 B oprd2 相当于 oprd1.operator B(oprd2)程序举例:#include using namespace std; class Complex private: int real; int imag
6、; public: Complex(int r,int i) real = r; imag = i; Complex() void disp() cout real + imag ireal temp.imag = imag + c2.imag;/this-imag return temp; ; void main(void) Complex c1(1,2); c1.disp(); Complex c2(3,4); c2.disp(); Complex c3; /c3 = c1 + c2; /c3 = c1.operator +(c2);/与上面c3 = c1+c2等价,但上面的写法要简洁清晰
7、些。 /c3 = 10 + c1;/错误!不能10.operator+(c1) /c3 = c1 + 10;/错误!c1.operator+(10) c3.disp();4)前置单目运算符 U如果要重载 U 为类成员函数,使之能够实现表达式 U oprd,其中 oprd 为A类对象,则 U 应被重载为 A 类的成员函数,无形参。经重载后,表达式 U oprd 相当于 oprd.operator U()5)后置单目运算符 +和-如果要重载 +或-为类成员函数,使之能够实现表达式 oprd+ 或 oprd- ,其中 oprd 为A类对象,则 +或- 应被重载为 A 类的成员函数,且具有一个 int
8、 类型形参。经重载后,表达式 oprd+ 相当于 oprd.operator +(0)+运算符号重载-成员函数程序举例 #include using namespace std; class Clock private: int hour; int second; int minute; public: Clock(int h=0,int m=0,int s=0) hour = h; second = s; minute = m; void disp() cout hour : minute: second = 60) second = second - 60; minute +; if( m
9、inute = 60) minute = minute - 60; hour +; if( hour = 24) hour = hour % 24;/使小时的值始终保持在0到24之间 return * this; ; void main(void) Clock c1(23,59,59); /c1+ ; /单独使用的时候,前置和后置是一样的 /c1.disp(); /+c1 ; /c1.disp(); /(c1+).disp(); /c1.operator +(0).disp();/与上面的一条语句等价 /(+c1).disp(); /c1.operator +().disp();/与上面的一条
10、语句等价2重载为友元函数:如果左边的操作数是不同类的一个对象或者是一个内部类型的对象,该运算符函数必须作为一个非成员函数来实现,如果运算符函数作为非成员函数直接访问该类的private或者protected数据成员,因此出于性能因素考虑,将运算符函数指定为类的友元函数(否则要使用Set或者get函数)。例如:重载运算符必须有一个ostream &类型的左操作数(如表达式cout 中的cin。选择非成员函数的另一个原因是使运算符具有可交换性。例如obj+number和number+obj(如同不同的加法),问题在于,如果作为成员函数重载,类对象必须出现在运算符的左边。设定为非成员函数不一定是友元
11、函数,只要类的public接口中有相应的set和get函数,set和get函数如果能内联则更好。1)重载为友元函数时 参数个数=原操作数个数,且至少应该有一个自定义类型的形参。2)如果需要重载一个运算符,使之能够用于操作某类对象的私有成员,可以此将运算符重载为该类的友元函数。3)函数的形参代表依自左至右次序排列的各操作数。4)后置单目运算符 +和-的重载函数,形参列表中要增加一个int,但不必写形参名。5)双目运算符 B重载后,表达式oprd1 B oprd2 等同于operator B(oprd1,oprd2 )程序举例:将+重载为类的友元函数 #include class Complex
12、private: int real; int imag; public: Complex(int r,int i) real = r; imag = i; Complex() void disp() std:cout real + imag istd:endl; friend Complex operator +(Complex c1,Complex c2) /将+重载为友元函数,参数个数跟实际一致 Complex temp; temp.real = c1.real + c2.real; temp.imag = c1.imag + c2.imag; return temp; ; void ma
13、in(void) Complex c1(1,2); c1.disp(); Complex c2(3,4); c2.disp(); Complex c3(5,6); /c3 = c1 + c2; /c3 = operator+(c1,c2);/与上面等价 /c3.disp();6)前置单目运算符 B重载后,表达式 B oprd 等同于operator B(oprd )7)后置单目运算符 +和-重载后,表达式 oprd B 等同于operator B(oprd,0 )#include using namespace std; class Clock private: int hour; int s
14、econd; int minute; public: Clock(int h=0,int m=0,int s=0) hour = h; second = s; minute = m; void disp() cout hour : minute: second = 60) c1.second = c1.second - 60; c1.minute +; if( c1.minute = 60) c1.minute = c1.minute - 60; c1.hour +; if( c1.hour = 24) c1.hour = c1.hour % 24; return c1; ; void main(void) Clock c1(23,59,59); / (c1+).disp(); / operator+(c1,0).disp(); /(+c1).disp(); operator+(c1).disp(); 课后作业
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1