运算符重载
C++基础系列——运算符重载

C++基础系列——运算符重载1. 运算符重载简介所谓重载,就是赋予新的含义。
函数重载(Function Overloading)可以让⼀个函数名有多种功能,在不同情况下进⾏不同的操作。
同样运算符重载(Operator Overloading)可以让同⼀个运算符可以有不同的功能。
可以对 int、float、string 等不同类型数据进⾏操作<< 既是位移运算符,⼜可以配合 cout 向控制台输出数据也可以⾃定义运算符重载:class Complex{public:Complex();Complex(double real, double imag);Complex operator+(const Complex &a) const;void display() const;private:double m_real;double m_imag;};// ...// 实现运算符重载Complex Complex::operator+(const Complex &A) const{Complex B;B.m_real = this->m_real + A.m_real;B.m_imag = this -> m_imag + A.m_imag;return B;// return Complex(this->m_real + A.m_real, this->m_imag + A.m_imag);}int main(){Complex c1(4.3, 5.8);Complex c2(2.7, 3.7);Complex c3;c3 = c1 + c2; // 运算符重载c3.display();return 0;}运算结果7 + 9.5i运算符重载其实就是定义⼀个函数,在函数体内实现想要的功能,当⽤到该运算符时,编译器会⾃动调⽤这个函数,它本质上是函数重载。
运算符重载

// 顺序错误
.
27
由于使用友元会破坏类的封装,要尽量将运算 符重载函数定义为成员函数。
除非有特殊需要,才使用友元函数重载运算符。
.
28
4.5重载双目运算符
双目的意思是运算符左边和右边的操作数均参 加运算。
如果要重载 B 为类的成员函数,使之能够实 现表达式 oprd1 B oprd2,其中 oprd1 为A 类 对象,则 B 应被重载为 A 类的成员函数,形 参类型应该是 oprd2 所属的类型。
.
24
加法运算符重载为友元函数,C++ 在编译时将表达式 c1+c2解释为
operator + ( c1, c2) 即相当于执行以下函数
Complex operator + ( Complex & c1, Complex & c2 ) {
return Complex( c1.real + c2.real , c1.imag + c2.imag ) ; }
.
3
运算符重载的实质
运算符重载是对已有的运算符赋予多重含义。
必要性:C++中预定义的运算符其运算对象只 能是基本数据类型,而不适用于用户自定义类 型(如类)
实现机制
将指定的运算表达式转化为对运算符函数的调用, 运算对象转化为运算符函数的实参。
编译系统对重载运算符的选择,遵循函数重载的选 择原则。
friend Complex operator + ( int & i , Complex & c )
{
return Complex( c.real + i , c.imag ) ;
第八讲 运算符重载(8.2)

另一类是“=”即直接赋值的运算符
#include <iostream.h> class Vector { int x,y; public: Vector(){}; Vector(int x1,int y1){x=x1;y=y1;} 对于标准数据类型,“+=”和”-=”的作 friend Vector operator +=(Vector v1,Vector v2) //友 用是将一个数据与另一个数据进行加法和 元函数方式实现 { 减法运算后,再将结果回送给赋值号左边 v1.x+=v2.x; v1.y+=v2.y; return v1; } Vector operator -=(Vector v) //成员函数方式实现 的变量中。对它们重载后,使其实现其他 { Vector tmp; tmp.x=x-v.x; 相关的功能 tmp.y=y-v.y; return tmp; } void display(){cout<<"("<<x<<","<<y<<")"<<endl; } }; void main() { Vector v1(6,8),v2(3,6),v3,v4; cout<<"v1=";v1.display();cout<<"v2=";v2.display(); v3=v1+=v2; cout<<"v3=v1+=v2后,v3=";v3.display(); v4=v1-=v2; cout<<"v4=v1-=v2后,v4=";v4.display();
c++学习资料第 06 章 运算符重载

第 6 章 运 算 符 重 载
{ return Complex( c.Real, c.Image ); } void Complex::print()const { cout << '(' << Real << " , " << Image << ')' << endl; } void main() { Complex c1( 2.5,3.7 ), c2( 4.2, 6.5 ) ; Complex c ; c = c1 c2 ; // operator(c1,c2) c.print() ; c = 25 + c2 ; // operator+(25,c2) c.print() ; c = c2 + 25 ; // operator+(c2,52) c.print() ; c = c1 ; // operator(c1) c.print() ; } 当一个运算符的操作需要修改类对象状态时,应该以成员函数重载。例如,需要左值操 作数的运算符(如 =,*=,++ 等)应该用成员函数重载。如果以友员函数重载,可以使用 引用参数修改对象。 当运算符的操作数(尤其是第一个操作数)希望有隐式转换,则重载算符时必须用友员 函数或普通函数。 C++中不能用友员函数重载的运算符有 = () [] -> 6.3 几个典型运算符重载 本节讨论在数学类中常用的几个运算符重载的特点和应用。 6.3.1 重载 ++ 与 自增和自减运算符有前置和后置两种形式。每个重载运算符的函数都必须有明确的特 征,使编译器确定要使用的版本。C++规定,前置形式重载为一元运算符函数,后置形式重 载为二元运算符函数。 【例 64】例 62 中使用了成员函数重载++和运算符。本例用友员函数重载++运算符。 设有简单类定义 class Increase { public : Increase() ; … friend Increase operator ++ ( Increase & ) ; friend Increase operator ++ ( Increase & , int ) ; private : unsigned value ; } ; 则前置重载的实现为: Increase operator++ ( Increase & a ) { a.value ++ ;
4第四章 运算符重载

const complex operator - (const complex &c) const; void display(); //输出复数 private: //私有数据成员 1.是为了堵塞a+b=c的漏洞。 double real; //复数实部 2. 3.是为了扩大适应性。 double imag; //复数虚部 };
17
[ ]运算符重载为成员函数
下标运算符[]可以重载: 重载形式为:operator[](int); 当 X x; 隐含调用。 x[y] 可被解释为: 显式调用。 x. operator [ ](y); 只能重载为成员函数,不能使用友元函数。 这个类显然是个‚数组类‛。
18
前置++和后置++重载为成员函数
9
使用
void main(){
complex c1(5,4),c2(2,10),c3; //三个复数类的对象 cout<<"c1="; cout<<"c2="; c1.display(); c2.display();
c3=c1-c2; //使用重载运算符完成复数减法 cout<<"c3=c1-c2="; c3.display(); 程序输出结果为:
这三个运算符是许多 教课书没有提到的。
唯一的一个三目运 算符不能重载。
3
运算符重载的基础
设计运算符重载函数,首先要了解运算符原本的运算语义。重
载函数要忠实遵守该运算符作用于基本数据类型时的语义,
并表现出自身所特有的性质。 例如:+ 、+= 、=、++(前)、++(后) ....
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; ▪}
运算符重载

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. 逻辑运算符重载逻辑运算符包括条件运算符和逻辑非运算符。
每个逻辑运算符都有一组默认的行为,可以通过运算符重载来自定义它们的行为。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第7章运算符重载
本章学习要点
❖为什么要进行运算符重载 ❖运算符重载的方法 ❖重载运算符的规则 ❖运算符重载函数作为类成员函数和友元函数 ❖重载双目运算符 ❖重载单目运算符 ❖重载流插入运算符和流提取运算符 ❖不同类型数据间函数名多个含义。 ❖运算符重载是指同一个运算符可以施加于不同
但我们希望在程序中直接用运算符“+” 对Money类的对象进行相加运算。
total1 = cost1 + cost2;
对运算符“+” 进行重载以后,就可以 这样书写了。
7
7.1 为什么要进行运算符重载 ❖有了针对自定义类型数据的运算符重
载,不仅使我们编程时感到十分方便 ,而且写出的表达式与数学表达式很 相似,符合人们的习惯。
int main( ) { Money cost1(300, 5, 6),cost2(105, 7, 6), total1;
total1 = MonetAdd(cost1,cost2); total1.Display("total1 = cost1 + cost2"); return 0;} 5
class Money {public: Money(int y = 0, int j = 0, int f = 0) { yuan = y; jiao = j; fen = f; optimize( ); } void Display(string); Money MoneyAdd(Money &c2); private: int yuan, jiao, fen; void Optimize( );}; void Money::Optimize( ) { if ( fen >= 10 ){ jiao++; fen -=10; }
if ( jiao >= 10 ){ yuan++; jiao -=10; } }
void Money::Display(string str)
{ cout << str << " = " << yuan << "." << jiao << fen << "¥" <<
endl; } 4
class Money {public: Money(int y = 0, int j = 0, int f = 0) { yuan = y; jiao = j; fen = f; optimize( ); } void Display(string);
if ( jiao >= 10 ){ yuan++; jiao -=10; } } void Money::Display(string str) { cout << str << " = " << yuan << "." << jiao << fen << "¥" << endl; } Money MoneyAdd(Money &c1,Money &c2) { return Money( c1.yuan + c2.yuan, c1.jiao + c2.jiao, c1.fen + c2.fen ); }
if ( jiao >= 10 ){ yuan++; jiao -=10; } } void Money::Display(string str) { cout << str << " = " << yuan << "." << jiao << fen << "¥" << endl; } Money Money::MoneyAdd (Money &c2) { return Money ( yuan + c2.yuan, jiao + c2.jiao, fen + c2.fen ); }
9
7.2 运算符重载的方法 【例7-1】对“+”运算符进行重载来实现
两个Money类对象的加法运算。
10
#include <iostream>
int main( )
#include <string>
{ Money cost1(300, 5, 6), cost2(105, 7, 6),
using namespace std;
8
7.2 运算符重载的方法
函数名
❖重载运算符的函数的一般格式如下: 函数类型 operator运算符名称(形参列表) { 对运算符的重载处理 }
函数名是由operator和运算符组成,如 operator+意思是对运算符“+”重载。
重载运算符的函数可以是类的成员函数,也 可以是类的友元函数,还可以是既非类的成 员函数也非类的友元函数的普通函数
friend Money MoneyAdd(Money &c1,Money &c2); private: int yuan, jiao, fen; void Optimize( );}; void Money::Optimize( ) { if ( fen >= 10 ){ jiao++; fen -=10; }
int main( ) { Money cost1(300, 5, 6),cost2(105, 7, 6), total1;
total1 = cost1.MonetAdd(cost2); total1.Display("total1 = cost1 + cost2"); return 0;} 6
7.1 为什么要进行运算符重载
int yuan, jiao, fen; void Optimize( );//优化函数
Money cost2(5, 8, 2), total; total = cost1 + cost2;
};
void Money::Optimize( )
{ if ( fen >= 10 ){ jiao++; fen -=10; }
类型的操作数上面。
3
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);