第7章 运算符重载
第12-13讲 运算符重载

7.1.2 运算符重载规则
可以重载C++中除下列运算符外的所有运算符: 类属关系运算符. 成员指针运算符* 作用域分辨符:: sizeof运算符 三目运算符?: 只能重载C++语言中已有的运算符,不可臆造新的。 不能改变操作数个数。 不能改变原运算符的优先级和结合性。 不能改变运算符对预定义类型数据的操作方式。 经重载的运算符,其操作数中至少应该有一个是自定 义类型。
14
void complex:: print()//显示输出复数 { cout<<real; if(imag>0) cout<<"+"; if(imag!=0) cout<<imag<<"i";cout<<endl; } void main() { complex A1(2.3,4.6),A2(3.6,2.8),A3,A4,A5,A6;//定义6个复数类对象 A1.print(); A2.print(); A3=A1+A2; A3.print(); A4=A1-A2; A4.print(); A5=A1*A2; A5.print(); A6=A1/A2; A6.print(); }
2
class complex { public: double real,imag; //定义一个实部,一个虚部变量 complex(double r=0,double i=0) { real=r; imag=I; } }; main() { complex com1(1.1,2.2),com2(3.3,4.4),total; total=com1+com2; 错误,2个自定义的数据类 return 0; 型complex类型对象相加, } C++无法实现. 希望实现total=com1+com2;重载“+”
简述运算符重载的规则

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

运算符重载运算符重载 (1)0.运算符重载一般概念 (2)1.运算符重载规则 (2)1.1. 允许重载的运算符 (2)1.2. 不允许重载的运算符 (2)1.3. 其他规则 (3)2.运算符重载普通函数、友员函数和类成员函数 (3)3.单目预算符、双目运算符重载 (4)4.转换构造函数和类型转换运算符 (4)5.赋值运算符的重载 (5)6. []下标运算符重载 (6)7. new和delete重载 (6)8.指针运算符->的重载 (7)运算符重载一般概念C++内部定义的数据类型(int , float, …)的数据操作可以用运算符号来表示,其使用形式是表达式,用户自定义的类型的数据的操作则用函数表示,其使用形式是函数调用。
为了是对用户自定义数据类型的数据的操作与内定义的数据类型的数据的操作形式一致,C++提供了运算符的重载,通过把C++中预定义大的运算符重载为类的成员函数或者友员函数,使得对用户的自定义数据类型的数据—对象的操作形式与C++内部定义的类型的数据一致。
重载即赋予新的含义。
运算符重载指对已知的运算符,在新的场合,通过程序实现新的行为。
什么时候重载需要对象间相互赋值时,重载赋值运算符需要数字类型算术运算时,重载算术运算符需要进行逻辑比较时,重载关系运算符对于容器,重载下标运算符[]需要输入输出时,重载<<和>>运算符重载成员指针运算符-> 以实现smart指针在少数情况下重载new,delete运算符不重载其他运算符0.运算符重载规则0.1.允许重载的运算符表 1.1 允许重载的运算符0.2.不允许重载的运算符不允许重载的运算符只有5个:. (成员访问符).* (成员指针访问运算符):: (域运算符)sizeof (长度运算符)?: (条件运算符号)0.3.其他规则不允许自己定义新的运算符,只能对已有的运算符号进行重载;重载不能改变运算符运算对象的个数,如>和<是双目运算符,重载后仍为双目运算符,需要两个参数;重载不能改变运算符的结合性,如=是从右至左,重载后仍然为从右至左;重载不能改变运算符的优先级别,例如* / 优先于+-,那么重载后也是同样的优先级别;重载运算符的函数不能有默认的参数,否则就改变了运算符参数的个数,与第2条矛盾;重载的运算符必须和用户的自定义数据类型一起使用,其参数至少应有一个是类对象(或者类对象的引用),或者说参数不能全部是C++的标准类型;运算符重载函数可以是类的成员函数,也可以是类的友员函数,也可以使普通函数。
C_运算符重载_各类详细介绍

▪ 说明
运算符重载函数 operator@()可以返回任何类型,甚至可 以是 void类型,但通常返回类型与它所操作的类的类型 相同,这样可使重载运算符用在复杂的表达式中。例如, 在例7-2中,可以将几个复数连续进行加、减、乘、除的 运算。
用友元函数重载单目运算符时,需要一个显式的操作数, 例7-3中,用友元函数重载单目运算符“-”
#include<iostream.h> class nclass{ int a,b; public:
nclass(int x=0,int y=0) { a=x;b=y;} friend nclass operator -(nclass obj); void show(); };
▪ complex operator+(complex com1,complex com2) { return complex(com1.real+com2.real,com1.imag+com2.imag;}
▪ 这种方法是直接将一个无名临时对象创建到主调函数中,那么 运行效率高于前一种。
▪ 单目运算符重载
nclass operator-(nclass obj) { obj.a=-obj.a;
obj.b=-obj.b; return obj;} void nclass::show() { cout<<"a="<<a<<" b"<<b;} ▪ main() ▪{ ▪ nclass ob1(10,20),ob2; ▪ ob1.show(); ▪ ob2=-ob1; ▪ ob2.show(); ▪ return 0; ▪}
实验七-运算符重载参考答案

实验七-运算符重载参考答案实验七多态性—函数与运算符重载7.1 实验目的1.理解掌握成员函数方式运算符重载;2.理解掌握友元函数方式运算符重载;3.理解掌握++、--运算符的重载。
7.2 实验内容7.2.1程序阅读1.理解下面的程序,并运行查看结果,回答程序后面的问题。
#include <iostream>using namespace std;class CComplex{public:CComplex(){real = 0;imag = 0;}CComplex(int x,int y){real = x;imag = y;}int real;int imag;CComplex operator + (CComplex obj1)//---------------------------------------------①{CComplex obj2(real - obj1.real, imag - obj1.imag);return obj2;}};int main(){CComplex obj1(100,30);CComplex obj2(20, 30);CComplex obj;obj = obj1+obj2; //------------------------------------------------------------------②cout << obj.real <<endl;cout << obj.imag << endl;return 0;}问题一:①处的运算符重载,为什么该函数的返回值要设计成CComplex类型?答:因为在函数中return obj2,obj2是CComplex 类型,所以函数返回值要与return返回的类型相同,即设计成CComplex类型。
问题二:②处的运算符重载函数调用就相当于“obj=operator+(obj1,obj2);”,但是为什么CComplex类中的运算符重载函数只设计了一个参数?答:因为成员函数经编译后会产生this指针,this指针会指向调用该函数的obj1对象,该obj1对象就是就相当于函数的第一个参数。
运算符重载

运算符重载为类的友元函数
类中的声明: 类中的声明: friend 函数类型 operator 运算符(参数表); 运算符(参数表); 运算符重载函数的定义形式: 运算符重载函数的定义形式: 运算符(参数表) 函数类型 operator 运算符(参数表) { 函数体; 函数体; } 附加例) (附加例)用友元函数实现复数的加法运算符的重 载。
数据类型转换 标准数据类型转换
隐式转换: 自动转成double型) 隐式转换:7.5+2 (将2自动转成 将 自动转成 型 显式转换: 转成整型) 显式转换:int(89.5) (将89.5转成整型 将 转成型
涉及到类类型的转换
对于用户自己声明的类型, 对于用户自己声明的类型,编译系统并不知道怎样进行转 换。解决这个问题的关键是让编译系统知道怎样去进行转 换,需要定义专门的处理函数。 需要定义专门的处理函数。 将一个其他类型的数据转换成一个类类型: 将一个其他类型的数据转换成一个类类型:转换构造函数 将一个类的对象转换成另一类型的数据: 将一个类的对象转换成另一类型的数据:类型转换函数
运算符重载的格式
运算符重载为类的成员函数 运算符重载为类的友元函数
运算符重载的规则
①
② ③ ④ ⑤
.”、 *” ::”、 ?:”和 sizeof”等几个运 除“. 、“*”、“:: 、“?: 和“sizeof 等几个运 算符不能重载外, 算符不能重载外,C++中几乎所有的运算符都可以 中几乎所有的运算符都可以 重载。 重载。 运算符被重载后,其优先级和结合性不会改变。 运算符被重载后,其优先级和结合性不会改变。 不能改变运算符操作对象的个数。 不能改变运算符操作对象的个数。 运算符的意义应不变。 运算符的意义应不变。 用于类对象的运算符一般必须重载,但有两个例外, 用于类对象的运算符一般必须重载,但有两个例外, 运算符“ 和 不必用户重载。 运算符“=”和“&”不必用户重载。 不必用户重载
运算符重载——精选推荐

运算符重载运算符重载学习运算符重载,让运算符能做⼀些原来做不了的事情,⽅便它的使⽤⼀、运算符重载的概念1、什么是运算符重载1.重载:重新载⼊,就像之前学的函数重载,对⼀个已有的函数赋值⼀个新的定义,因此同⼀个函数名就可以有不同的含义。
2.运算符也是可以重载的,⽐如cout在输出⼀个变量的时候,能接受不同类型的数据并输出,他就是重载了<<运算符,这个就是运算符重载3.所以运算符重载指的是对已有的运算符重新定义新的运算规则,以适应不同的数据类型,当然重载之后之前的运算规则还是有的2、为什么要进⾏运算符重载1.运算符重载之后可以让运算符去适应不同的数据类型,对于基本数据类型,系统给出了运算符的操作规则,对于⾃定义数据类型来说,系统不知道该给出什么规则class student{int id;int age;char name[20];public:student(int id,int age,const char* name){this->id=id;this->age=age;strcpy(this->name,name);}}student stu1(1,23,"张三");student stu2(2,24,"李四");stu1+stu2;//如果是这样相加,那么应该加的是什么呢?编译器是不知道的,所以编译器就提供了运算符重载这个机制,让⽤户⾃定义运算符的运算规则⼆、运算符重载1、运算符重载类中定义1.关键字:operator,通过关键字来定义运算符重载(跟写个函数⼀样)2.定义:函数返回值类型 operator 要加载的运算符(参数列表){函数体;}这⾥把运算符的使⽤,理解为调⽤函数,只是和平时的调⽤函数有⼀点区别#include<iostream>#include<string>using namespace std;class student{int id;int age;string name;public:student(int age){this->age = age;id = 1;name = "sss ";}student(int id, int age, string name){this->id = id;this->age = age;this->name = name;}void showstudent(){cout << id << "\t" << age << "\t" << name << endl;}student operator+(student& p1)//这个函数会返回⼀个新的对象{int x=this->age + p1.age;student p(x);return p;//返回的是⼀个对象,会调⽤拷贝构造}int operator-(int x){return this->id - x;}void operator+(student&p2){cout << this->id + p2.id << endl;}};//1.操作这个运算符之后,返回值类型是什么int main(){student p1(0, 1, "yunfei");int x = p1.operator-(1);cout << x << endl;student stu1(1, 23, "张三");student stu2(2, 24, "李四");//student stu3 = stu1.operator+(stu2);//student stu3 = stu1 + stu2;stu1 + stu2;//stu3.showstudent();system("pause");return 0;}注意:因为我们这个运算符是在类中写的,所以是通过对象调⽤的,那么this指针会占⼀个参数,⽽且是第⼀个参数,也就是说我们重载⼀个运算符,是在类中,⽽这个运算符是个单⽬运算符,那么参数列表就不⽤写东西了,是双⽬运算符,那么就需要传另⼀个参数进来绝⼤部分的运算符重载都可以参照上⾯这个+号重载2、运算符重载的特点1.⼏乎所有的运算符都可以被重载,除了 . :: ()?() ) sizeof()2.运算符重载基本出现在类中和结构体中3.运算符可以理解为函数的⼀个表现3、运算符重载的注意事项1.重载运算符,这个重载的运算符还是满⾜原来的原则,但不能说重载+号,结果做的事-号的事,这样会使运算符的运⽤上增加很⼤的难度2.运算符重载的参数,类中重载调⽤对象会占⼀个参数,就是this会占⼀个参数,参数列表就是⽤来表⽰运算符的操作的3.对于运算符重载的调⽤,可以直接使⽤运算符,也可以通过对象 . 出来调⽤4.考虑返回值,不同的运算符有不同的返回值,要记得满⾜运算符原来的规则4、使⽤友元函数,实现运算符重载1.类在已经实现且部分修改的情况下下,需要进⾏运算符重载,就可以通过友元的⽅式来进⾏重载#include<iostream>#include<string>using namespace std;class person{int id;int age;string name;public:person(int id, int age, string name){this->id = id;this->age = age;this->name = name;}void showperson(){cout << id << "\t" << age << "\t" << name << endl;}friend int operator+(person&p1, person&p2);};//形参使⽤的是类对象的引⽤,在实参传对象的时候不会调⽤拷贝构造int operator+(person&p1, person&p2){return p1.id + p2.id;}//1.操作这个运算符之后,返回值类型是什么int main(){person stu1(1, 23, "张三");person stu2(2, 24, "李四");int x = operator+(stu1, stu2);//显⽰调⽤int y = stu1 + stu2;//隐式调⽤cout << x << endl << y << endl;system("pause");return 0;}容器:#include<iostream>#include<vector>using namespace std;int main(){//int 是v1这个容器存的类型vector<int> v1;for (int i = 0; i < 10; i++){//push_back()是⼀个函数,功能是尾插元素v1.push_back(i + 1);}for (int i = 0; i < 10; i++){cout << v1[i] << "\t";}system("pause");return 0;}左移右移运算符重载:#include<iostream>using namespace std;class person{int id;public:person(int id){this->id = id;}friend ostream& operator<<(ostream& os, person& p1);friend istream & operator>>(istream & in, person & p2);};//左移右移运算符重载,必须在类外重载,通过友元实现ostream& operator<<(ostream& os, person& p1)//左移运算符{os << p1.id << endl;return os;//返回的是⼀个cout,⽽且只能⽤引⽤}istream & operator>>(istream & in, person & p2)//右移运算符{in >> p2.id;return in;}int main(){person p1(10), p2(20);cin >> p1 >> p2;cout << p1 << endl << p2 << endl;system("pause");return 0;}前++,后++运算符重载:#include<iostream>using namespace std;class person{int id;public:person(int id){this->id = id;}person& operator++()//前++{this->id++;return *this;}person& operator++(int)//后++,int是⼀个占位符,⽤来区分前++和后++的{static person temp = *this;//引⽤不能返回局部变量,要⽤静态变量this->id++;return temp;}friend ostream& operator<<(ostream& os, person& p1);friend istream & operator>>(istream & in, person & p2);};//左移右移运算符重载,必须在类外重载,通过友元实现ostream& operator<<(ostream& os, person& p1)//左移运算符{os << p1.id << endl;return os;//返回的是⼀个cout,⽽且只能⽤引⽤}istream & operator>>(istream & in, person & p2)//右移运算符{in >> p2.id;return in;}int main(){person p1(10), p2(20);//cin >> p1 >> p2;//cout << p1 << endl << p2 << endl;cout << p1 ;//10cout << p1++ ;//10cout << p1 ;//11cout << ++p1 ;//12cout << p1 ;//12system("pause");return 0;}等号运算符重载:#include<iostream>using namespace std;class person{char* name;public:person(const char* name){this->name = new char[strlen(name) + 1];strcpy(this->name, name);}person& operator=(person&p1)//⽤不⽤引⽤传参,要看返回的对象会不会消失 {if (this->name != NULL){delete[]this->name;this->name = NULL;}this->name = new char[strlen() + 1];strcpy(this->name, );return *this;}void show(){cout << name << endl;}~person()//如果有申请函数,就要加上析构函数{if (name != NULL){delete[]name;name = NULL;}}};int main(){{person p1("张三"), p2("李四"), p3("王五");p1 = p2 = p3;p1.show();p2.show();p3.show();}//加上⼤括号,让对象死亡,就能调⽤析构函数system("pause");return 0;}智能指针和==号运算符重载:#include<iostream>using namespace std;class person{int id;public:person(int id){this->id = id;}void show(){cout << id << endl;}bool operator==(person& p){return this->id == p.id;}~person(){cout << "person的析构函数" << endl;}};class smartpointer{person* ps;//包含你要new出来的对象的类的指针public:smartpointer(person* p){ps = p;}//重载->person* operator->()//传回来的是地址,不是对象,不⽤引⽤{return ps;}//重载*person& operator*()//返回的是对象,会调⽤拷贝构造,所以⽤返回值⽤引⽤,就不会再调⽤拷贝构造了 {return *ps;//得到⼀个对象,}~smartpointer(){if (ps != NULL){delete ps;ps = NULL;}}};int main(){{smartpointer p(new person(5));p->show();(*p).show();person p1(1), p2(3);cout << (p1 == p2) << endl;}//有三个对象,所以析构函数执⾏了三次system("pause");return 0;}[]运算符重载:#include<iostream>using namespace std;class person{char* name;public:person(const char* name){this->name = new char[strlen(name) + 1];strcpy(this->name, name);}char& operator[](int index){return name[index];}~person(){if (name != NULL){delete[]name;name = NULL;}cout << "这是析构函数" << endl;}};int main(){person p("asdfg");cout << p[3] << endl;system("pause");return 0;}c++引⽤作为函数返回值:1.以引⽤返回函数值,定义函数时需要在函数名前加 &2.⽤引⽤返回⼀个函数值的最⼤好处是,在内存中不产⽣被返回值的副本3.返回值为引⽤的时候,返回的是⼀个地址,隐形指针4.当返回值不是引⽤时,编译器会专门给返回值分配出⼀块内存的引⽤作为返回值,必须遵守以下规则:(1)不能返回局部变量的引⽤。
第七章 函数的重载

7
实现函数重载
函数重载是通过在类中定义两个或更多的同名的函 数来实现函数重载。 数来实现函数重载。 在函数重载中, 在函数重载中,函数的每个定义必须在函数签名中 不同。 不同。
8
函数签名
函数的签名被下面的部分定义: 函数的签名被下面的部分定义:
参数的数量 参数的类型 参数的顺序 返回类型不是函数签名的一部分
public class DaysInYear { private int days; public DaysInYear(int days) 1.DaysInYear DIY = new DaysInYear(); { 2.DaysInYear DIY = new DaysInYear(5); this.days = days; 3.DaysInYear DIY = new DaysInYear("5"); } public DaysInYear(String dayOne) 4.DaysInYear DIY = new DaysInYear(‘5’); 5.DaysInYear DIY; { days =Convert.ToInt32(dayOne); } 1.错误 错误 public void setDay(int newDays) 2.调用int构造函数 调 构造函数 { 3.调用string构造函数 调 构造函数 days = newDays; 4.调用int构造函数 调 构造函数 } 5.没有对象生成,需要 没有对 或者让 没有 象生成,需要new或者让它指向一 或者 … 个DaysInYear对象 对 }
函数重载: 函数重载:这个方法允许为两个或更多函数使用同样 的名字。 的名字。函数的每个重新定义必须使用不同的参数类 参数顺序或多个参数。 型、参数顺序或多个参数。 操作符重载: 操作符重载:这个方法允许用户定义的类型例如结构 和类,为使它们的对象易于操作而使用重载操作符。 和类,为使它们的对象易于操作而使用重载操作符。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
这种表示复数加法 很不直观
运算符函数
class complex{ / / very simplified complex double re, im; public: complex(double r, double i) : re(r) , im(i) { } complex operator+(complex) ; complex operator*(complex) ; 运算符 }; 函数
简单复数类的运算符重载
#include<iostream.h> class complex //复数类声明 { public: //外部接口 complex(double r=0.0,double i=0.0) {real=r;imag=i;} //构造函数 complex operator + (complex c2); //+重载为成员函数 complex operator - (complex c2); //-重为载成员函数 void display( ); //输出复数 private: //私有数据成员 double real; //复数实部 double imag; //复数虚部 };
第7章
运算符重载
7.1 重载运算符的目的 7.2 运算符重载语法 7.3 成员运算符函数 7.4 友元运算符函数 7.5 成员运算符函数与友元运算符函数比较 7.6 ―++‖和“--‖的重载 7.7 赋值运算符“=‖的重载 7.7 下标运算符”[ ]‖与函数调用运算符”( )‖的重 载 7.9 构造函数用于类型转换 7.10 应用举例
时钟类例子(续5)
程序运行结果为:
First time output:23:59:59 Clock++: 0:0:0 ++Clock: 0:0:1
7.7 赋值运算符―=‖的重载
• 如果没有为类显式地定义赋值运算符,编译器 将自动产生一个缺省的赋值运算符函数,它执 行以字节为单位的复制操作。 • 注意operator=()函数的两个重要特点:
简单复数类的运算符重载(续)
//重载运算符函数的实现 complex complex::operator +(complex c2) { complex c; c.real=c2.real+real; c.imag=c2.imag+imag; return complex(c.real,c.imag); }
时钟类例子(续4)
//其它成员函数的实现略 void main( ) { Clock myClock(23,59,59); cout<<"First time output:"; myClock.ShowTime(); myClock++; myClock.ShowTime(); ++myClock; myClock.ShowTime(); }
《C++面向对象程序设计》教学内容
第1章 C++概述 第2章 类和对象 第3章 面向对象程序设计概述 第4章 进一步学习类和对象 第5章 堆与复制构造函数 第6章 继承性:派生类 第7章 运算符重载 第8章 虚函数和多态性 第9章 模板 第10章 类库和C++的标准模板库STL 第11章 输入输出流 第12章 异常处理
复数类的友元运算符函数
#include<iostream.h> class complex //复数类声明 { public: //外部接口 complex(double r=0.0,double i=0.0) { real=r; imag=i; } //构造函数 friend complex operator + (complex c1,complex c2); //运算符+重载为友元函数 friend complex operator - (complex c1,complex c2); //运算符-重载为友元函数 void display(); //显示复数的值 private: //私有数据成员 double real; double imag; };
7.1 重载运算符的目的
• • • • 简略的表达方法 函数式的表达方法 运算符函数 运算符重载
简略的表达方法
x+y*z
简略的表达方法是一种缩略或公式化表达 的方法。
好处:简明直观、能提高交流效率。
ห้องสมุดไป่ตู้
函数式的表达方法
class Complex{ private: double real; double image; public: Complex( ); Complex& Add(Complex&); }; //… Complex object1,object2,object3; …… object3 =object1.Add(object2);
运算符重载
void f( ) { complex a = complex(1, 3.1) ; complex b = complex(1.2, 2) ; complex c = b; a = b+c; b = b+c*a; c = a*b+complex(1,2) ; }
7.2 运算符重载语法
• 运算符重载
• 首先在类定义时说明待重载的运算符,其格式为: 返回值类型 operator op (参数表);
• 然后象定义函数一样定义重载运算符函数。
返回值类型 类名称∷operator op(参数表)
{ //…… 运算符处理程序代码 }
运算符重载的实质
• 必要性
– C++中预定义的运算符其运算对象只能是 基本数据类型,而不适用于用户自定义类 型(如类)
简单复数类的运算符重载(续)
//重载运算符 - 函数实现 complex complex::operator - (complex c2) { complex c; c.real=real-c2.real; c.imag=imag-c2.imag; return complex(c.real,c.imag); }
简单复数类的运算符重载(续)
void complex::display( ) { cout<<"("<<real<<","<<imag<<")"<<endl; } void main() //主函数 { complex c1(5,4),c2(2,10),c3; //定义复数类的对象 cout<<"c1="; c1.display(); cout<<"c2="; c2.display(); c3=c1-c2; //使用重载运算符完成复数减法 cout<<"c3=c1-c2="; c3.display(); c3=c1+c2; //使用重载运算符完成复数加法 cout<<"c3=c1+c2="; c3.display(); }
时钟类例子(续3)
void Clock::operator ++(int) //后置单目运算符重载 { Second++; if(Second>=60) { Second=Second-60; Minute++; if(Minute>=60) {Minute=Minute-60; Hour++; Hour=Hour%24; } } cout<<"Clock++: "; }
时钟类例子(续1)
#include<iostream.h> class Clock //时钟类声明 { public: //外部接口 Clock(int NewH=0, int NewM=0, int NewS=0); void ShowTime(); void operator ++(); //前置单目运算符重载 void operator ++(int); //后置单目运算符重载 private: //私有数据成员 int Hour, Minute, Second; };
成员和友元运算符函数
class complex{ double re,im; 双目运算符
public:
complex(double r, double I) { re=r; im=i; }
成员函数
complex( ) { re=im=0; } complex operator+(complex ); complex operator++( );
• 实现机制
– 运算符重载的实质就是函数重载:每个运 算符对应各自的运算符函数,根据操作数 的不同调用不同的同名函数。 – 将指定的运算表达式转化为对运算符函数 的调用,运算对象转化为运算符函数的实 参。
7.3 成员运算符函数
• 重载为类成员函数时 参数个数=原操作数个数-1 (后置++、--除外) • 当类的对象调用这种运算符函数时,对象中的成 员数据就可以是一个操作数,另一个操作数才通过 参数传递来获得。 • 如: class complex {public complex operator + (complex c2); ……. }
简单复数类的运算符重载(续)
程序输出的结果为: c1=(5,4) c2=(2,10) c3=c1-c2=(3,-6) c3=c1+c2=(7,14) 注:交换c1和c2的位置,不影响结果。
7.4 友元运算符函数
• 重载为友元函数时 参数个数=原操作数个数,且 至少应该有一个自定义类型的形参。 • 友元函数是类以外的函数,调用这种运算符函数时, 所有的操作数都要通过参数传递来获得。 如: class complex {public friend complex operator + (complex c1, complex c2); ……. }