7 运算符重载
第7章 运算符重载

减法
乘法 除法 小于 ......
目录 退出
7.1.2 运算符重载的规则
运算符重载是针对新类型数据的实际需要,对
原有运算符进行适当的改造完成的。一般来讲,重
载的功能应当与原有的功能相类似。
只能重载C++预定义中已有的运算符,不可自己
“创造”新的运算符进行重载。
第10页 共125页
第21页 共125页
目录
退出
例7.2 用友元运算符进行复数运算
complex::complex(double r,double i) { real=r; imag=i; } complex operator+(complex a,complex b) { complex temp; temp.real=a.real+b.real; temp.imag=a.imag+b.imag; return temp; }
第15页 共125页
目录
退出
7.2.1 友元运算符函数
友元运算符函数定义的语法形式
双目运算符重载
单目运算符重载
第16页 共125页
目录
退出
友元运算符函数定义的语法形式
友元运算符函数的原型在类的内部声明格式如
下:
class X { //… friend 返回类型 operator运算符(形参表); //… }
第30页 共125页
目录
退出
例7.4 使用友元函数重载“++”, “--”时有问题
#include <iostream.h> class coord{ public: coord(int i=0,int j=0); void print( ); friend coord operator++(coord op); private: int x,y; }; coord::coord(int i,int j) {x=i;y=j;}
第7章 函数重载和运算符重载

7.3 运算符重载
•7.3.2 单目运算符的重载 单目运算符重载时参数只有一个。
class Matrix{ public: Matrix operator –( ); //其他成员 //成员函数,参数表为空
}; Matrix Matirx::operator –( ) { Matirx m(rows,cols); //临时对象 for(int i=0;i<rows;i++) for(int j=0;j<cols;j++) m(m,j)= –(*this)(i,j); return m; }
7.3 运算符重载
Matrix & Matrix::operator=(Matrix &src) { //将 src 的所有元素都复制过来 for(int i=0;i<rows*cols;i++) mem[i]=src.mem[i]; return *this; }
7.3 运算符重载
3. 插入抽取运算符的重载 我们可以通过重载插入和抽取运算符来 获得这种效果。重载的运算符形式如下:
7.3 运算符重载
•7.3.4 特殊运算符的重载 1. 自增自减运算符的重载 如果将自增自减运算符定义为类的成员函数, 则应该没有参数。但是为了区分前缀和后缀, C++规定:后缀自增自减运算符定义时带有一 个整型参数,而前缀自增自减运算符时不带 参数,这样在编译时,系统就知道所重载的 是前缀还是后缀运算符了。
7.3 运算符重载
运算符的重载形式有两种,一种是重载为类 的成员函数,另一种是重载为独立的运算符 函数,一般是作为类的友元函数。运算符重 载的语法形式如下: <函数类型> operator <运算符> (<形参表>) { <函数体> }
实验七-运算符重载参考答案

实验七-运算符重载参考答案实验七多态性—函数与运算符重载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对象就是就相当于函数的第一个参数。
运算符重载的方法

运算符重载的方法
运算符重载是指在类中重新定义某个运算符,使其能够用于类的实例。
重载运算符可以方便地对类对象进行加、减、乘、除等基本运算,也可以定义自定义运算符,以实现类特定的功能。
运算符重载的方法如下:
1.编写运算符重载函数:将要重载的运算符的符号作为函数名,如“+”、“-”、“*”、“/”等,对于自定义运算符可以自己命名。
2.指定参数个数和类型:重载函数需要参数,这些参数有不同的类型,可以是类的成员变量或其他类型的变量。
3.重载运算符要求:
(1)操作数至少有一个是类的实例,重载函数可以定义为类的成员函数或全局函数。
(2)运算符重载不能改变原有操作数的类型或个数。
(3)运算符重载函数可以返回任何类型的值,甚至可以是类的实例。
4.使用运算符:一旦重载运算符函数定义好之后,就可以像使用普通的运算符一样使用它。
需要注意的是,运算符重载不是万能的,对于某些运算符,如“&&”、“”等,是不能够重载的。
此外,在使用运算符重载时应该避免过于复杂的实现方式,以防止代码难以理解和维护。
运算符重载

24
运算符重载
思考:如果希望表达式i+c1有意义, 思考:如果希望表达式i+c1有意义,应该 i+c1有意义 如何定义重载运算符函数? 如何定义重载运算符函数?
friend Complex operator+(int &i,Complex &c); Complex operator+(int &i, Complex &c) {return Complex(i+c.real,c.imag);}
2
什么是运算符重载
代码分析: 代码分析: 例10.1 通过函数来实现复数 相加。 相加。
CCS E
3
运算符重载的方法
运算符重载的方法是定义一个重载运 算符的函数, 算符的函数,在需要执行被重载的运 算符时,系统就自动调用该函数, 算符时,系统就自动调用该函数,以 实现相应的运算。也就是说, 实现相应的运算。也就是说,运算符 重载是通过定义函数实现的。 重载是通过定义函数实现的。运算符 重载实质上是函数的重载。 重载实质上是函数的重载。
CCS E
21
运算符重载
如果将运算符重载函数作为成员函数, 如果将运算符重载函数作为成员函数, 它可以通过this this指针自由地访问本类 它可以通过this指针自由地访问本类 的数据成员, 的数据成员,因此可以少写一个函数 的参数。 的参数。但必须要求运算表达式第一 个参数(即运算符左侧的操作数) 个参数(即运算符左侧的操作数)是一 个类对象, 个类对象,而且与运算符函数的类型 相同。 相同。因为必须通过类的对象去调用 该类的成员函数,而且只有运算符重 该类的成员函数, 载函数返回值与该对象同类型, 载函数返回值与该对象同类型,运算 结果才有意义。 结果才有意义。
简述运算符重载的规则。

简述运算符重载的规则。
篇一:运算符重载是C/C++语言中一种强大的功能,允许程序员自定义函数的行为,以处理不同类型的数据。
运算符重载允许程序员在函数中重载算术、逻辑和位运算符,从而能够处理数组、结构体和指针等不同类型的数据。
以下是运算符重载的规则:1. 算术运算符重载算术运算符包括加号、减号、乘号和除号。
每个算术运算符都有一组默认的行为,可以通过运算符重载来自定义它们的行为。
例如,重载加号运算符可以使函数接受一个整数参数,并返回一个新的整数。
下面是一个简单的例子,演示了如何重载加号运算符:```c++struct MyStruct {int value;};MyStruct operator+(const MyStruct& other, int value) {return MyStruct(value + other.value);}int main() {MyStruct mystruct1 = { 10 };MyStruct mystruct2 = { 20 };int result = mystruct1 + mystruct2;std::cout << "result = " << result << std::endl;return 0;}```在上面的例子中,我们定义了一个名为`MyStruct`的结构体类型,其中包含一个整数类型。
然后,我们定义了一个重载加号运算符的函数,该函数接受一个整数类型的参数,并返回一个新的`MyStruct`对象。
在`main`函数中,我们定义了两个`MyStruct`对象`mystruct1`和`mystruct2`,并将它们相加,结果存储在`result`变量中。
2. 逻辑运算符重载逻辑运算符包括条件运算符和逻辑非运算符。
每个逻辑运算符都有一组默认的行为,可以通过运算符重载来自定义它们的行为。
Python编程基础之运算符重载详解

Python编程基础之运算符重载详解
⽬录
学习⽬标
⼀、运算符重载
(⼀)概述
(⼆)加法运算重载符
1、概述
2、案例演⽰
总结
学习⽬标
1.掌握运算符重载
2.会定制对象字符串的形式
⼀、运算符重载
(⼀)概述
运算符重载是通过实现特定的⽅法使类的实例对象⽀持Python的各种内置操作。
例如:+运算符是类⾥提供的__add__这个函数,当调⽤+实现加法运算的时候,实际上是调⽤了__add__⽅法。
⽅法说明何时调⽤⽅法
__add__加法运算对象加法:x+y,x+=y
__sub__减法运算对象减法:x-y,x-=y
__mul__乘法运算对象乘法:xy,x=y
__div__除法运算对象除法:x/y,x/=y
__getitem__索引,分⽚x[i]、x[i:j]、没有__iter__的for循环等
__setitem__索引赋值x[i]=值、x[i:j]=序列对象
__delitem__索引和分⽚删除del x[i]、del x[i:j]
(⼆)加法运算重载符
1、概述
加法运算是通过调⽤__add__⽅法完成重载的,当两个实例对象执⾏加法运算时,⾃动调⽤__add__⽅法。
2、案例演⽰
编写程序 - 演⽰加法运算符重载.py
运⾏程序,查看结果
如果两个数组长度不相等,那么就会抛出异常
总结
本篇⽂章就到这⾥了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!。
运算符重载——精选推荐

运算符重载运算符重载学习运算符重载,让运算符能做⼀些原来做不了的事情,⽅便它的使⽤⼀、运算符重载的概念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)不能返回局部变量的引⽤。
运算符重载——精选推荐

运算符重载什么是运算符的重载?运算符与类结合,产⽣新的含义。
为什么要引⼊运算符重载?作⽤:为了实现类的多态性(多态是指⼀个函数名有多种含义)怎么实现运算符的重载?⽅式:类的成员函数或友元函数(类外的普通函数)规则:不能重载的运算符有 . 和 .* 和 ?: 和 :: 和 sizeof友元函数和成员函数的使⽤场合:⼀般情况下,建议⼀元运算符使⽤成员函数,⼆元运算符使⽤友元函数1、运算符的操作需要修改类对象的状态,则使⽤成员函数。
如需要做左值操作数的运算符(如=,+=,++)2、运算时,有数和对象的混合运算时,必须使⽤友元3、⼆元运算符中,第⼀个操作数为⾮对象时,必须使⽤友元函数。
如输⼊输出运算符<<和>>具体规则如下:运算符建议使⽤所有⼀元运算符成员函数= ( ) [ ] ->必须是成员函数+= -= /= *= ^= &= != %= >>= <<= , 似乎带等号的都在这⾥了成员函数所有其它⼆元运算符, 例如: –,+,*,/友元函数<< >>必须是友元函数2. 参数和返回值当参数不会被改变,⼀般按const引⽤来传递(若是使⽤成员函数重载,函数也为const).对于返回数值的决定:1) 如果返回值可能出现在=号左边, 则只能作为左值, 返回⾮const引⽤。
2) 如果返回值只能出现在=号右边, 则只需作为右值, 返回const型引⽤或者const型值。
3) 如果返回值既可能出现在=号左边或者右边, 则其返回值须作为左值, 返回⾮const引⽤。
运算符重载举例:+和 -运算符的重载:class Point{private:int x;public:Point(int x1){ x=x1;}Point(Point& p){ x=p.x;}const Point operator+(const Point& p);//使⽤成员函数重载加号运算符friend const Point operator-(const Point& p1,const Point& p2);//使⽤友元函数重载减号运算符};const Point Point::operator+(const Point& p){return Point(x+p.x);}Point const operator-(const Point& p1,const Point& p2){return Point(p1.x-p2.x);}输出:Point a(1);Point b(2);a+b; //正确,调⽤成员函数a-b; //正确,调⽤友元函数a+1; //正确,先调⽤类型转换函数,把1变成对象,之后调⽤成员函数a-1; //正确,先调⽤类型转换函数,把1变成对象,之后调⽤友元函数1+a; //错误,调⽤成员函数时,第⼀个操作数必须是对象,因为第⼀个操作数还有调⽤成员函数的功能1-a; //正确,先类型转换后调⽤友元函数总结:1、由于+ -都是出现在=号的右边,如c=a+b,即会返回⼀个右值,可以返回const型值2、后⼏个表达式讨论的就是,数和对象混合运算符的情况,⼀般出现这种情况,常使⽤友元函数3、双⽬运算符的重载:重载运算符函数名:operator@(参数表)隐式调⽤形式:obj1+obj2显式调⽤形式:obj1.operator+(OBJ obj2)---成员函数operator+(OBJ obj1,OBJ obj2)---友元函数执⾏时,隐式调⽤形式和显式调⽤形式都会调⽤函数operator+()++和--运算符的class Point{private:int x;public:Point(int x1){ x=x1;}Point operator++();//成员函数定义⾃增const Point operator++(int x); //后缀可以返回⼀个const类型的值friend Point operator--(Point& p);//友元函数定义--friend const Point operator--(Point& p,int x);//后缀可以返回⼀个const类型的值};Point Point::operator++()//++obj{x++;return *this;}const Point Point::operator++(int x)//obj++{Point temp = *this;this->x++;return temp; // 需要返回⼀个临时对象,效率不如 ++obj ⾼}Point operator--(Point& p)//--obj{p.x--;return p;//前缀形式(--obj)重载的时候没有虚参,通过引⽤返回*this 或⾃⾝引⽤,也就是返回变化之后的数值}const Point operator--(Point& p,int x)//obj--{Point temp = p;p.x--;return temp;// 后缀形式obj--重载的时候有⼀个int类型的虚参, 返回原状态的拷贝}调⽤:Point b(2);a++;//隐式调⽤成员函数operator++(0),后缀表达式++a;//隐式调⽤成员函数operator++(),前缀表达式b--;//隐式调⽤友元函数operator--(0),后缀表达式--b;//隐式调⽤友元函数operator--(),前缀表达式cout<<a.operator ++(2);//显式调⽤成员函数operator ++(2),后缀表达式cout<<a.operator ++();//显式调⽤成员函数operator ++(),前缀表达式cout<<operator --(b,2);//显式调⽤友元函数operator --(2),后缀表达式cout<<operator --(b);//显式调⽤友元函数operator --(),前缀表达式 </pre>总结:1、a++函数返回:temp(临时变量)函数返回是否是const类型:返回是⼀个拷贝后的临时变量),不能出现在等号的左边(临时变量不能做左值),函数的结果只能做右值,则要返回⼀个const类型的值++a函数返回:*this;函数返回是否是const类型:返回原状态的本⾝,返回值可以做左值,即函数的结果可以做左值,则要返回⼀个⾮const类型的值2、前后缀仅从函数名(operator++)⽆法区分,只能有参数区分,这⾥引⼊⼀个虚参数int x,x可以是任意整数。
c程序设计课件第7章运算符重载

2
class Money
{public: Money(int y = 0, int j = 0, int f = 0)
构造函数
{ yuan = y; jiao = j; fen = f; optimize( ); }
void Display(string);
private:
Money cost1(10, 3, 5);
if ( jiao >= 10 ){ yuan++; jiao -=10; } }
void Money::Display(string str)
{ cout << str << " = " << yuan << "." << jiao << fen << "¥" <<
endl; } 3
class Money {public: Money(int y = 0, int j = 0, int f = 0) { yuan = y; jiao = j; fen = f; optimize( ); } void Display(string);
调用:total1 = cost1 + cost2; 形参的顺序任意,不要求第一个参数必须为类对象。要
求运算符左侧的操作数与第一个参数对应,运算符右侧
的操作数与第二个参数对应。
13
7.3 重载运算符的规则
❖(1)C++不允许用户自己定义新的运算符,只 能对C++语言中已有的运算符进行重载。例如 ,虽然在某些程序设计语言中用双字符“**” 作为求幂运算符,但是在使用C++进行程序设 计时,不能将“**”作为运算符进行重载,因 为“**”不是C++语言的合法运算符。
运算符重载解读

02
在重载运算符时,应明确指定 运算符的参数类型和返回类型 ,避免与其他操作符混淆。
03
在重载运算符时,应尽量使用 有意义的操作符名称,以提高 代码的可读性。
考虑性能和效率
01
02
03
运算符重载时,应考虑 性能和效率,避免对原 有代码造成不必要的性
能损失。
在重载运算符时,应尽 量减少额外的计算和内 存开销,以提高代码的
一元运算符重载
一元运算符重载是指对一元运算符进行重载,使其能够应用于一个操作数。例如,在C中,我们可以 重载一元减号运算符(-)来返回一个数的相反数。
常见的一元运算符有:+、-、~、!等。
二元运算符重载
二元运算符重载是指对二元运算符进行重载,使其能够应用于两个操作数。例如,在C中,我们可以重载加号运算符(+)来定 义两个自定义类型的相加行为。
01
提高代码可读性
运算符重载可以使代码更易读, 因为运算符的使用可以使代码更 简洁、更直观。
02
03
方便函数调用
运算符重载可以使得函数调用更 加方便,因为运算符的使用可以 减少函数调用的开销。
04
缺点分析
易造成混淆
运算符重载可能会使得代码难以理解,因为 运算符的行为可能会被改变,导致读者难以
理解代码的含义。
常见的二元运算符有:+、-、*、/、%等。
三元运算符重载
三元运算符重载是指对三元运算符进行重载,使其能够应用于三个操作数。例如,在C中,我们可以重载条件运 算符(?)来定义一个自定义类型的条件判断行为。
常见的三元运算符有:?:。
03
运算符重载的常见场景
类与类之间的运算
01
两个类对象之间的加法运算,可以表示它们之间的某种关联或 合并。
第7讲 运算符重载

第7讲运算符重载字符串和数组对象本讲主要内容y运算符重载的基础知识与限制y以成员函数/友元函数方式重载运算符y流插入/提取运算符的重载方法y单目/双目运算符的重载方法y类型转换运算符重载方法y运算符重载实例研究y数组类y字符串类y Date类运算符重载概念(1/4)y 回顾“函数重载”y 定义多个同名函数来表示类似的操作,只要这些函数有不同参数(参数的个数、类型或顺序不同)int abs(int i);long abs(long l);double abs(double d);y 运算符重载(Operator Overloading)y 运算符可以被视为一种函数,也能够被重载1 +2+(1, 2)+(int, int) 1.0 +2.0+(1.0, 2.0)+(double, double)运算符重载概念(2/4)y运算符作为函数y使程序变得非常清晰、简单y把传统的运算符用于用户自定义的对象y直观自然,可以提高程序的可读性y C++的可扩充性:C++不允许定义新的运算符,但允许运算符重载运算符重载概念(3/4)y重载运算符函数名:y operator 重载的运算符y示例y Complex operator+(const Complex&) const;y Complex operator-(const Complex&) const;y Complex& operator=(const Complex&);y friend ostream & operator<<(ostream &output, Complex&);y注意保持重载运算符在语义上与运算符的原始经典语义的相似性运算符重载概念(4/4)y当要把自定义类的对象用作运算符的操作数时,运算符必须重载y特例:赋值运算符= 、地址运算符& 和逗号,可(无需重载)直接应用于对象的操作y C++的所有运算符都可以被重载吗?y. .* :: ?: sizeof 不能被重载y运算符重载实现途径y保持运算符的原有属性,作为类的成员函数或友元函数y特例:( ) [ ] -> = 的重载只能作为成员函数运算符重载的限制y①不能改变运算符的优先级y②不能改变运算符的结合律y③不能改变运算符操作数的个数y④不能用默认参数重载运算符(即重载运算符的函数不能有默认参数)y⑤不能创建新的运算符y⑥不能改变运算符作用于基本类型时的含义y⑦运算符重载只能对用户自定义类型的对象y⑧重载运算符()、[]、->、=时,重载函数必须声明为类的成员函数y⑨运算符都必须显式重载用作类成员与友元函数的运算符重载函数比较y运算符重载函数既可以是成员函数,也可以是非成员函数——全局函数,出于性能考虑,这里的全局函数通常是友元函数y成员函数是用this指针隐式地访问类对象的某个参数y友元函数的调用必须显示地列出参数运算符重载:成员函数or友元函数(1/6 )y运算符的重载函数定义为类的成员函数y当该成员函数不带参数时,支持以该类对象为唯一操作数的运算class String { public:String();~String();bool operator !(); private:char *str;};main(){String s ...if ( !s)...}s.operator!();运算符重载:成员函数or友元函数(2/ 6)y运算符的重载函数定义为类的成员函数y当该成员函数带一个参数时,支持以该类对象为左操作数、以所带参数类型的数据为右操作数的运算class String {public:...String & operator+=(String &s); private:char *str;main( ){ String s1,s2; ...s1+=s2; ...}s1.operator+=(s2);成员函数or友元函数(3/ 6)y运算符的重载函数定义为类的友元函数y当该函数带一个参数时,支持以该参数类型的对象为唯一操作数的运算class String {friend bool operator !(String &s); public:... private: char *str;main(){String s ...if ( !s )...}operator!(s);成员函数or友元函数(4/ 6)y运算符的重载函数定义为类的友元函数y当该函数带两个参数时,支持以第一个参数类型的数据为左操作数、以第二个参数类型的数据为右操作数的运算class String {friend String& operator+=(String &x, String &y);...String & operator+=(String &x, String &y)main(){String s1,s2;...s1+=s2;…operator+=(s1, s2);}成员函数or友元函数(5/ 6)y在包含对象的双目运算中,当双目运算符的左操作数不是某类的对象时,重载函数必须定义为该类的友元函数y例如:流插入运算符<<的重载class String {friend ostream & operator<<(ostream &output, String &s);friend istream & operator>>(istream &input, String &s);...private:char *str;main(){String s1,s2;cin >> s1 >> s2;cout << s1 << s2 << endl;...}运算符重载:成员函数or 友元函数(6/6 )y 运算符可交换性的实现——友元函数y 运算符重载函数的定义要保证运算无二义性class Complexpublic:Complex(double = 0.0, double = 0.0);Complex operator+(const Complex&) const;Complex operator-(const Complex&) const;Complex& operator=(const Complex&);Complex obj,obj1, obj2 obj = obj1 + obj2obj1 = 1 + obj2obj1 = obj2 + 1class Complex{friend Complex operator+(int, const Complex&) const;friend Complex operator+(const Complex&, int) const;public:Complex(double = 0.0, double = 0.0); Complex& operator=(const Complex&);...};运算符重载函数小结y到底是成员函数还是友元函数?y运算符重载作为成员函数实现时,最左操作数必须是运算符所属类的对象(或引用对象)y当操作数为不同类对象或者基本类型对象时,必须作为全局函数(即友元函数)实现运算符重载y对于具可交换性的运算符,应选择友元函数实现运算符重载重载流插入和流提取运算符y语句y cout << "string";y能在标准输出设备上输出字符串"string"y cout是类ostream的一个对象y如何实现:String s("string");cout << s << endl;将运算符函数operator<<定义为类ostream的成员函数或友元函数将运算符函数operator<<定义为类String的成员函数 将运算符函数operator<<定义为类String的友元函数示例:电话号码类的输入/出y教材P103~104代码class PhoneNumber {friend ostream &operator<<( ostream&, const PhoneNumber & ); friend istream &operator>>( istream&, PhoneNumber & ); private:char areaCode[ 4 ];// 区号char exchang[ 4 ];// 交换局号段char line[ 5 ];// 线路号ostream &operator<<( ostream &output, const PhoneNumber &num){output << "(" << num.areaCode << ")"<< num.exchange <<"-"<< num.line;return output;// enables cout << a << b << c; }单目运算符重载(1/ 3)y单目运算符(Unary Operators)y只有一个操作数y当作为(非static)成员函数重载y没有参数y注意:static成员函数只能访问类的static数据成员y当作为友元函数重载y参数为自定义类的对象或对象的引用单目运算符重载(2/ 3)y特殊的单目运算符++、--y以++ 为例( --同理),设b为类B的对象前自增,如:++ by重载函数可作为B的成员函数,原型为返回值类型operator++();++b 转换为函数调用b.operator++()y重载函数也可作为B的友元函数,原型为返回值类型operator++(B &);++b 转换为函数调用operator++(b)单目运算符重载(3/ 3)y特殊的单目运算符++、--y以++ 为例( --同理),设b为类B的对象后自增,如:b ++y重载函数可作为B的成员函数,原型为返回值类型operator++(int);b++转换为函数调用b.operator++(0)y重载函数也可作为B的友元函数,原型为返回值类型operator++(B &, int);b++转换为函数调用operator++(b,0)双目运算符重载y一般双目运算符的重载要考虑两个因素:y被重载运算符的左操作数是什么数据类型y是否要保留运算符的可交换性(只针对具有可交换性的运算符而言)y双目运算符的重载可实现为y带有一个参数的非static成员函数(左操作数必须为该类的对象或对象的引用)bool operator<(const String &)const;y带有两个参数的非成员函数(其参数之一必须是类的对象或对象的引用)friend bool operator<(const String &, const String &);实例研究:Array类y基于指针的数组存在问题:y数组下标的越界问题y下标范围不可选y不能一次性输入/输出整个非字符数组y每个数组元素必须单独读取/写入y不能用相等运算符或者关系运算符比较两个数组y数组作为函数参数时,数组的大小必须作为一个额外的参数传递给该函数y不能用赋值运算符把一个数组赋给另一个数组y……类型转换(1/2 )y如何实现用户自定义类型和其它类型之间的转换?y通过转换构造函数实现将其它类型的数据转换成自定义类的对象y通过类型转换运算符函数实现将自定义类的对象转换成其它类型的数据y类型转换运算符函数必须是类的非static成员函数,不能是友元函数y类型转换运算符函数没有参数(如同单目运算符作为成员函数重载)y不能指定返回类型(因为类型转换符已经指定了返回类型)类型转换(2/ 2)y类型转换运算符函数原型的例子:operator int() const;如果obj是该自定义类的一个对象,则(int)obj 或int(obj)将会产生函数调用obj.operator int( )该函数将根据调用它的对象obj生成一个int类型的数据并返回该数据。
运算符重载详解

运算符重载详解1.运算符重载定义:C++中预定义的运算符的操作对象只能是基本数据类型。
但实际上,对于许多⽤户⾃定义类型(例如类),也需要类似的运算操作。
这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够⽤于特定类型执⾏特定的操作。
运算符重载的实质是函数重载,它提供了C++的可扩展性,也是C++最吸引⼈的特性之⼀。
运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进⾏的操作。
运算符函数的定义与其他函数的定义类似,惟⼀的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。
运算符函数定义的⼀般格式如下:<返回类型说明符> operator <运算符符号>(<参数表>){<函数体>} 2.运算符重载时要遵循以下规则:(1) 除了类属关系运算符"."、成员指针运算符".*"、作⽤域运算符"::"、sizeof运算符和三⽬运算符"?:"以外,C++中的所有运算符都可以重载。
(2) 重载运算符限制在C++语⾔中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。
(3) 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。
(4) 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。
(5) 运算符重载不能改变该运算符⽤于内部类型对象的含义。
它只能和⽤户⾃定义类型的对象⼀起使⽤,或者⽤于⽤户⾃定义类型的对象和内部类型的对象混合使⽤时。
(6) 运算符重载是针对新类型数据的实际需要对原有运算符进⾏的适当的改造,重载的功能应当与原有功能相类似,避免没有⽬的地使⽤重载运算符。
(7)重载运算符的函数不能有默认的参数,否则就改变了运算符的参数个数,与前⾯第3点相⽭盾了;(8)重载的运算符只能是⽤户⾃定义类型,否则就不是重载⽽是改变了现有的C++标准数据类型的运算符的规则了,会引会天下⼤乱的;(9)⽤户⾃定义类的运算符⼀般都必须重载后⽅可使⽤,但两个例外,运算符“=”和“&”不必⽤户重载;(10)运算符重载可以通过成员函数的形式,也可是通过友元函数,⾮成员⾮友元的普通函数。
《运算符重载》PPT课件_OK

bool operator>=(const Rational &r1) const;
bool operator!=(const Rational &r1) const;
11
void display() { cout << num << '/' << den; }
}
函数实现
Rational Rational::operator+(const Rational &r1) const { Rational tmp;
4
可以重载的运算符
+-*/%^ ~ ! = < > += /= %= ^= &= |= <<= == != <= >= -- ->* , -> [] () new[] delete[]
& -= << && new
| *= >> >>= || ++
delete
5
不能重载的运算符
. .* :: ?: sizeof
Rational operator*(const Rational &r1, const Rational &r2)
{ Rational tmp;
tmp.num = r1.num * r2.num;
tmp.den = r1.den * r2.den;
tmp.ReductFraction(); return tmp;
tmp.num = num * r1.den + r1.num * den; tmp.den = den * r1.den; tmp.ReductFraction(); return tmp; }
第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;重载“+”
【免费下载】7运算符重载

除了 new 和 delete 这两个较为特殊运算符以外,任何运算符如果作为成员函数重载时 不得重载为静态函数。=、[ ]、()、->以及所有的类型转换运算符只能作为成员函数重载, 而且不能是针对枚举类型操作数的重载。
2重载取负运算符“-”
因为 fraction 用分子的符号代表整个分数的符号,因此所谓“取负”只需对分子 num 取负就可以了。由于取负运算符“-”是一元运算符,当作为成员函数重载时参数表中没有
对全部高中资料试卷电气设备,在安装过程中以及安装结束后进行高中资料试卷调整试验;通电检查所有设备高中资料电试力卷保相护互装作置用调与试相技互术关,系电,力根通保据过护生管高产线中工敷资艺设料高技试中术卷资,配料不置试仅技卷可术要以是求解指,决机对吊组电顶在气层进设配行备置继进不电行规保空范护载高与中带资负料荷试下卷高问总中题体资,配料而置试且时卷可,调保需控障要试各在验类最;管大对路限设习度备题内进到来行位确调。保整在机使管组其路高在敷中正设资常过料工程试况中卷下,安与要全过加,度强并工看且作护尽下关可都于能可管地以路缩正高小常中故工资障作料高;试中对卷资于连料继接试电管卷保口破护处坏进理范行高围整中,核资或对料者定试对值卷某,弯些审扁异核度常与固高校定中对盒资图位料纸置试,.卷保编工护写况层复进防杂行腐设自跨备动接与处地装理线置,弯高尤曲中其半资要径料避标试免高卷错等调误,试高要方中求案资技,料术编试交写5、卷底重电保。要气护管设设装线备备置敷4高、调动设中电试作技资气高,术料课中并3中试、件资且包卷管中料拒含试路调试绝线验敷试卷动槽方设技作、案技术,管以术来架及避等系免多统不项启必方动要式方高,案中为;资解对料决整试高套卷中启突语动然文过停电程机气中。课高因件中此中资,管料电壁试力薄卷高、电中接气资口设料不备试严进卷等行保问调护题试装,工置合作调理并试利且技用进术管行,线过要敷关求设运电技行力术高保。中护线资装缆料置敷试做设卷到原技准则术确:指灵在导活分。。线对对盒于于处调差,试动当过保不程护同中装电高置压中高回资中路料资交试料叉卷试时技卷,术调应问试采题技用,术金作是属为指隔调发板试电进人机行员一隔,变开需压处要器理在组;事在同前发一掌生线握内槽图部内 纸故,资障强料时电、,回设需路备要须制进同造行时厂外切家部断出电习具源题高高电中中源资资,料料线试试缆卷卷敷试切设验除完报从毕告而,与采要相用进关高行技中检术资查资料和料试检,卷测并主处且要理了保。解护现装场置设。备高中资料试卷布置情况与有关高中资料试卷电气系统接线等情况,然后根据规范与规程规定,制定设备调试高中资料试卷方案。