实验八 运算符重载及应用
一、实验目的
1.理解多态性概念及分类,熟悉C++中静态多态性的实现方法;
2.理解运算符重载的意义,掌握在C++中用成员函数及友元函数实现运算符重载的方法;
2.熟悉运算符重载的应用。
二、实验学时
课内实验:2课时 课外练习:2课时
三 本实验涉及的新知识
㈠ 多态性的概念及分类
1.多态性的概念
多态性是指不同对象在收到相同的消息时,产生不同的动作。即用同一个名字定义不同的函数,执行不同但相似的操作,从而实现“一个接口,多种方法”。
2.多态性的分类及实现方法
⑴ 静态多态性。亦称编译时多态性,即静态联编支持的多态性,在C++中通过函数重载及运算符重载实现。
⑵ 动态多态性。亦称运行时多态性,即动态联编支持的多态性,在C++中通过虚函数实现。
3.函数重载的方法
由前面实验中所涉及的知识可知,函数重载主要有以下方式:
⑴ 同一个类中的同名函数,可用参数个数不一样或参数类型不一样或参数个数及类型不一样实现重载。
⑵ 同一类中,普通成员函数与同名的常量成员函数,可通过“const”实现重载。 ⑶ 不同类中的同名函数,可通过类名调用或类的对象调用实现重载。
㈡ 运算符重载
1.运算符重载的意义及作用
C++中的运算符与函数一样,也可以实现重载,从而扩充C++预定义的运算符的作用范围。编程者可以通过重载运行符扩充运算符的功能,使编写的程序更符合人们的思维习惯,更易于理解。
2.重载的运算符
在C++中,大部分运算符可以重载,包括算术运算符、关系运算符、逻辑运算符、增量运算符、赋值运算符等。如:+、-、*、/、%、&、=、+=、-=、&&、||、!、++、[]、new、delete等(除不能重载的几个运算符外,均可以重载)。
不能重载的运算符有: ::—— 作用域运算符 . —— 成员访问运算符 .* —— 成员指针访问运算符 ?: —— 条件运算符
3.用成员函数重载运算符 ⑴ 格式
1
<返回类型> <类名>::operator@(参数表) { 函数体 }
其中:返回类型通常为类名(也可以为其它类型);operator是重载运算符必须使用的定义符;@ 表示所重载的运算符,如+、-、*、/等。
⑵ 重载双目运算符后的调用格式
① 显示调用:obj1.operator@ (obj2) ; ② 隐式调用:obj1@obj2 ; ⑶ 重载单目运算符后的调用格式 ① 显示调用:obj.operator@( ) ; ② 隐式调用:@obj ; ⑷ 说明
① 重载双目运算符时,运算符的左分量即为对象本身,用this指针表示,因此参数表中只有一个参数。
② 重载单目运算符时,惟一的运算分量是对象本身,用this指针表示,因此参数表中没有参数。
4.用友员函数重载运算符 ⑴ 格式
friend <返回类型> operator@(参数表) { 函数体 }
⑵ 重载双目运算符后的调用格式
① 显示调用:operator @ (obj1,obj2) ; ② 隐式调用:obj1@obj2 ; ⑶ 重载单目运算符后的调用格式 ① 显示调用: operator@( obj ) ; ② 隐式调用:@obj ; ⑷ 说明
由于友元运算符不是类的成员函数,无this指针,因此,当重载双目运算符时,参数表中有两个参数;当重载单目运算符时,参数表中有一个参数。
5.重载运算符应注意的问题
① 重载运算符不能改变原有运算符的含义。
② 重载运算符不能改变运算符的原有的优先级和运算分量的个数。 ③ 只能重载已有的运算符,即不能新造一个运算符。
④ 同一个运算符可以重载多次,调用时可根据参数的个数及类型决定调用哪个重载函数。
⑤ 通常,单目运算符的重载用成员函数,双目运算符的重载用友元函数。 ⑥ 运算符“=、( )、[ ]、->”的重载,只能用成员函数,不能用友元函数。 ⑦ 当双目运算符的运算分量有一个基本类型数据时,通常用友元运算符重载。
⑧ 增量运算符重载时,前置运算符与前面介绍的知识相同,而后置运算符增加一个int作为形参。
⑨ 赋值运算符“=”通常不需要重载,但当类的数据成员中有指针变量,需要用new分配内存,用delete释放内存时,必须重载。
四、实验内容
㈠ 验证及认知实验
按要求调试下列程序,并回答相关问题。
2
程序1(exp_701.cpp)
//用成员函数重载前置运算符“++” #include
coord(int i=0,int j=0); void print(); coord operator ++(); };
coord::coord(int i,int j) {x=i;y=j;}
void coord::print()
{ cout << \ y=\coord coord::operator ++() { ++x; ++y;
return *this; }
void main()
{ coord ob(10,20); ob.print(); ++ob; ob.print(); } 问题:
⑴ 编译运行程序的结果是:
⑵ 程序中前置运算符“++”采用的重载方式是 。 ⑶ 将重载函数“coord coord::operator ++()”中的“++x; ++y; ”改为:“++this->x; ++this->y ; ” 重新运行程序。
⑷ 将“main()”函数中的“++ob;”改为“ob.operator++( );”,重新运算程序。
程序2(exp_702.cpp)
//用友元函数重载两个复数相加:“+” #include
double real ; double imag; public :
3
complex(double r=0,double i=0) {real=r;imag=i;} void print();
complex operator+(complex c1,complex c2); };
complex operator+(complex c1,complex c2)//重载“+” { complex temp;
temp.real=c1.real+c2.real; temp.imag=c1.imag+c2.imag; return temp; }
void complex::print() {cout < if (imag>0) cout<<\ if (imag!=0) cout < void main() { complex A1(2.3,4.6),A2(3.6,2.8),A3; A3=A1+A2; A1.print();A2.print(); } 问题: ⑸ 编译程序时,将会出现编译错误,其原因是 。 ⑹ 将类中的“complex operator+(complex c1,complex c2);”的前面加上“friend”,重新编译调试程序,输出结果为: 。 ⑺ 将“main()”中的“A3=A1+A2;”改为“A3=operator(A1,A2);”,重新运行程序。 ㈡ 知识应用实验 按要求调试、完善程序。 程序3(exp_703.cpp) //用成员函数重载两个复数相加、减 #include double real ; double imag; public : complex(double r=0,double i=0) {real=r;imag=i;} 4 void print(); complex operator+(const complex &c); complex operator-(complex c); }; complex complex ::operator+(const complex &c)//重载“+” {complex temp; return temp; } complex complex ::operator-(complex c)//重载“-” {complex temp; return temp; } void complex::print() {cout < if (imag>0) cout<<\ if (imag!=0) cout < void main() { complex A1(2.3,4.6),A2(3.6,2.8),A3,A4; A3=A1+A2;A4=A1-A2; A1.print();A2.print(); A3.print();A4.print(); } 程序4(exp_704.cpp) //用成员函数重载前置、后置“++”及负号“-” #include coord(int i=0,int j=0); void print(); coord operator ++(); coord operator ++(int); coord operator -(); }; coord::coord(int i,int j) {x=i;y=j;} void coord::print() { cout << \ y=\ coord coord::operator ++() //重载前置运算符++ { return *this; } coord coord::operator ++(int)//重载后置运算符++ 5