第九章多态性 丘志杰 电子科技大学 计算机学院软件学院
第九章 多态性 丘志杰 电子科技大学 计算机学院 软件学院
什么是多态性 多态是指同样的消息被不同类型 的对象接收时导致完全不同的行 为 多态可以分为: 编译时的多态,如函数重载、运算 符重载 运行时的多态,虚函数 2021/2/10
2021/2/10 2 什么是多态性 • 多态是指同样的消息被不同类型 的对象接收时导致完全不同的行 为。 • 多态可以分为: – 编译时的多态,如函数重载、运算 符重载 – 运行时的多态,虚函数
运算符重载 当在使用一种程序设计语言编写程序时,我们 不仅要设计新的数据类型,同时还要为新类型 设计运算。一般地,用户定义类型的运算都是 用函数的方式实现的。而在一般情况下,基本 类型的运算都是用运算符表达的,这很直观, 语义也简单。 如果直接将运算符作用在用户定义类型之上, 那么编译器将不能识别运算符的语义。因此, 在这种情况下,我们需要一种特别的机制来重 新定义作用在用户定义类型上的普通运算符的 含义。这就是运算符重载的简单概念。 2021/2/10
2021/2/10 3 运算符重载 • 当在使用一种程序设计语言编写程序时,我们 不仅要设计新的数据类型,同时还要为新类型 设计运算。一般地,用户定义类型的运算都是 用函数的方式实现的。而在一般情况下,基本 类型的运算都是用运算符表达的,这很直观, 语义也简单。 • 如果直接将运算符作用在用户定义类型之上, 那么编译器将不能识别运算符的语义。因此, 在这种情况下,我们需要一种特别的机制来重 新定义作用在用户定义类型上的普通运算符的 含义。这就是运算符重载的简单概念
在C编译器里早就存在简单的运算符重载的 概念。考虑整型和浮点型两种加法运算: int ab,c: c=a+b: mov eax, dword ptr [ 4 add eax, dword ptr [ebp-81 mov dword ptr [ebp-oChl, eax float a, b, c, c=a+b; fld dword ptr [ebp-4] fadd dword ptr [ebp-81 fstp dword ptr [ebp-och 2021/2/10
2021/2/10 4 • 在C编译器里早就存在简单的运算符重载的 概念。考虑整型和浮点型两种加法运算: int a,b,c; c=a+b; mov eax,dword ptr [ebp-4] add eax,dword ptr [ebp-8] mov dword ptr [ebp-0Ch],eax float a,b,c; c=a+b; fld dword ptr [ebp-4] fadd dword ptr [ebp-8] fstp dword ptr [ebp-0Ch]
什么是运算符重载 在原来预定义的运算符含义的基础上 再定义对于某个用户定义类型的对象 进行操作的新的含义。这就是运算符 重载。 运算符重载后,其优先级和结合性不 变,所需的操作数也不能变。 2021/2/10
2021/2/10 5 • 在原来预定义的运算符含义的基础上, 再定义对于某个用户定义类型的对象 进行操作的新的含义。这就是运算符 重载。 • 运算符重载后,其优先级和结合性不 变,所需的操作数也不能变。 什么是运算符重载
重载运算符 大多数系统预定义的运算符可以重载, 但少数的C++运算符不能重载: #、?:、,、*、 另外,不是运算符的符号,如“;”等也 不能重载。C++还不允许重载不存在的 运算符,如“$” 等 2021/2/10
2021/2/10 6 重载运算符 • 大多数系统预定义的运算符可以重载, 但少数的C++运算符不能重载: :: 、#、 ?:、 .、.* 、 * • 另外,不是运算符的符号,如“;”等也 不能重载。C++还不允许重载不存在的 运算符,如“$” 、 “**”等
例:复数的加操作 class Complex& double re. im: public: Complex(doubler=0.0, double i=0.O): re(r), im(i) Complex add(complex c)t Complex t: tre= re+cre. t im= im t cim: return t: vold main c3=c1.ad(2):这种使用方式 Complex cl(1, 2), c2(3, 4); 不太直观。 Complex c33=c1ad(c2);·我们更希望是如下方式 C=CTC 2021/2/10
2021/2/10 7 例:复数的加操作 class Complex{ double re, im; public: Complex(double r=0.0, double i=0.0): re(r), im(i){ } Complex add(Complex c){ Complex t; t.re = re + c.re; t.im = im + c.im; return t; } }; void main( ) { Complex c1(1, 2), c2(3, 4); Complex c3 = c1.add(c2); } • c3 = c1.add(c2);这种使用方式 不太直观。 • 我们更希望是如下方式: c3=c1+c2;
例:重载复数类的加运算符 class Complex public: Complex operator+(Complex c) Complex t; t re=re c re; tim=im cim return t; }; void main( Complex cl(l, 2), c2(3, 4); Complex c3=c1+c2;相当于c3=c1. operator+(c2); operator+(,称为运算符重载函数 c3=c1+c2称为 operator+(,)函数的隐式调用 8 c3=c1. operator+(c2)称为 operator+(,)函数的显示调用
2021/2/10 8 例:重载复数类的加运算符 class Complex{ …… public: Complex operator+(Complex c){ Complex t; t.re = re + c.re; t.im = im + c.im; return t; } }; void main( ) { Complex c1(1, 2), c2(3, 4); Complex c3 = c1 + c2; //相当于c3 = c1.operator+(c2); } operator+(…)称为运算符重载函数 c3 = c1 + c2称为operator+(…)函数的隐式调用 c3 = c1.operator+(c2)称为operator+(…)函数的显示调用
例:计数器重载运算符 class counter unsigned int value; public: counter ivalue=0 void operator++o void operator--O unsigned int operator(o void counter: operator++ (if (value0)value--i unsigned int counter: operator(return value 2021/2/10 9
2021/2/10 9 例:计数器重载运算符 class counter{ unsigned int value; public: counter( ){value=0;} void operator++( ); void operator--( ); unsigned int operator( )( ); }; void counter:: operator++( ){if (value0) value--;} unsigned int counter:: operator( )( ){return value;}
void main( counter my counter; for(inti=0;<10;i++){ ++my counter cout<<“ my counter=“<< my counter()<<endl; my counter cout<<“ my counter=“<< my counter()<<endl; 2021/2/10 10
2021/2/10 10 void main( ) { counter my_counter; for(int i=0;i<10;i++){ ++my_counter; cout<<“my_counter=“<<my_counter( )<<endl; } --my_counter; cout<<“my_counter=“<<my_counter( )<<endl; }