第11章77 运算符重载

合集下载

11章运算符重载

11章运算符重载

考虑用普通函数实现两个复数相加
Complex complex_add(Complex &c1, Complex &c2) { Complex c; c.real=c1.real+c2.real; c.imag=c1.imag+c2.imag; return c; }
将其声明为Complex 类的友元函数
int operator + (int a, int b) {return (a-b);}
(8)用于类对象的运算符一般必须重载,但有两个例外,运算 符“=”和“&”不必用户重载。 ① 赋值运算符(=)可以用于每一个类对象,可以利用它在 同类对象之间相互赋值(系统已经为每一个新声明的类重载 了一个赋值运算符,他的作用是逐个复制类的数据成员)。 ② 地址运算符&也不必重载,它能返回类对象在内存中 的起始地址。 (9)应当使重载运算符的功能类似于该运算符作用于标准类型 数据时所实现的功能。 (10)运算符重载函数可以是类的成员函数,也可以是类的友 元函数,还可以是既非类的成员函数也不是友元函数的普通 函数。
后自增
在自增(自减)运算符重载函数中,增加一个int型形参,就是后置自 增(自减)运算符函数。
#include <iostream> Complex Complex::operator ++ (int) using namespace std; { //对象复制,保存修改前对象状态 class Complex Complex temp(*this); {public: real++; imag++; //对象自增 Complex( ) return temp; //返回的是自加前的对象 {real=0; imag=0;} } Complex(double r,double i) {real=r; imag=i;} void Complex∷display( ) //重载后自增++函数 cout<<″(″<<real<<″,″<<imag<<″i) Complex operator + { +(int); void display( ); ″<<endl;} private: int main( ) double real; { Complex c1(3,4),c2; double imag; c2=c1++; // c1. operator ++ (0) }; cout<<″c1=″; c1.display( ); cout<<″c2=″; c2.display( ); }

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

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运算符重载其实就是定义⼀个函数,在函数体内实现想要的功能,当⽤到该运算符时,编译器会⾃动调⽤这个函数,它本质上是函数重载。

第11章 运算符重载

第11章 运算符重载

• 这并不会引起任何编译错误,但将引起逻辑上的混乱。 因此,重载一个运算符时,其具体操作还应尽量与该 运算符的原始含义保持一致。
重载一元运算符为类运算符
• 由于类运算符的第一操作数约定为当前对象(隐含),所 以用成员函数实现一元运算符重载的格式为: type ClassName::operator 单目运算符( ) { … } //函数体 • “++”和“--”运算符的重载方法相似,但有前置和后置 之分,应在定义运算符重载函数时有所区分。 • 以“++”运算符的重载为例说明其实现的方法: type ClassName::operator++( ) //前置 { … } type ClassName::operator++(int)//后置 { … } • 仅有形式意义,无需再写形参名。
重载运算符为友元运算符
• 友元运算符:某运算符重载函数被定义为类的友元。 • 注意:友元没有this指针,因此,参与运算的操作数 都必须在运算符重载函数的参数表中明确说明。 • 类X的一元友元运算符的定义格式: type operator@(参数说明) { … }
• 参数为左操作数,是类X的对象或引用。 ++、--运算符:参数只能是类X的引用 +、-运算符:参数为类X的引用或对象
重载二元运算符为类运算符
• 若某运算符重载函数被定义为类的成员,则称该运算 符为该类的运算符,简称类运算符。 • 由于类运算符的第一操作数约定为当前对象(隐含),所 以定义二元类运算符重载函数的一般格式为: type ClassName::operator @ (Arg) { … } //函数体 type:函数返回值类型 ClassName:运算符重载函数所在的类名 operator:关键字,与其后的运算符一起构成函数 名,有区别于其他函数名。 @:一个重载的二元运算符 Arg:函数的形参表,即第二操作数。

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; ▪}

第11章运算符重载

第11章运算符重载

运算符重载函数是类成员函数
一元运算符 @表示要重载的运算符 表示要重载的运算符 隐式调用: 对象名 对象名@ 隐式调用:@对象名 或者 对象名 显示调用:对象.operator@( ) 显示调用:对象 二元运算符 隐式调用:对象名 对象名2 隐式调用:对象名1@对象名 对象名 显示调用:对象名1.operator@(对象名 对象名2) 显示调用:对象名 对象名
例如:下边是运算符重载的另一个例子,程序实现了复数的加 例如:下边是运算符重载的另一个例子, 和减运算。(二元操作符) 。(二元操作符 和减运算。(二元操作符)
#include <iostream> using namespace std; class Complex { public: Complex() { real=0.0;imag=0.0; } Complex(double r) { real=r; imag=0.0; } Complex(double r,double i) { real=r; imag=i; } Complex operator+(const Complex& c); Complex operator-(const Complex& c); friend void print(const Complex& c); private: double real,imag; };
运算符重载为友元函数形式
注意: 注意:友元函数重载运算符调用方式 @表示要重载的运算符 表示要重载的运算符 二元运算符 显示: 对象名1,对象名 显示:operator@(对象名 对象名 对象名 对象名2) 隐式:对象名1@对象名 对象名2 隐式:对象名 对象名 一元运算符 显示: 对象名) 显示:operator@(对象名 对象名 隐式: 对象名 对象名@ 隐式:@对象名 或者 对象名

第11章 运算符重载

第11章 运算符重载
15
► 1.
双目运算符重载为类的友元函数,形式如下:
所属类型 &obj1)
返回类型 operator op(const 所属类型 &obj1,const { …… // obj1和obj2分别对应两个运算对象 }
“obj1 op obj2” ► 相当于operator op(obj1,obj2)
► 经过重载后,表达式
17
15complex operator +(const complex &c1,const complex &c2) 16{ complex c3; 17 c3.real=c1.real+c2.real; 18 c3.imag=c1.imag+c2.imag; 19 return c3; 20 } 21complex operator -(const complex &c1,const complex &c2) 22{ complex c3; 23 c3.real=c1.real-c2.real; 24 c3.imag=c1.imag-c2.imag; 25 return c3; 26 } 27 int main() 28 { complex c1(1,2),c2(3,4),c3; 29 30 //输出4+6i c3=c2+c1; c3.display(); 31 c3=c2-c1; c3.display(); //输出2+2i return 0; 32 }
5
► 1.
双目运算符重载为类的成员函数,形式如下: 返回类型 类名::operator op(const 所属类型 { …… //this指针对应obj1运算对象 }
&obj2)

重载运算符语法讲解

重载运算符语法讲解重载运算符这篇随笔我来讲解⼀下C++语⾔中重载运算符的相关知识。

⼀、重载运算符的⽤途这是⼀个⽐较哲学的问题:我们为什么要重载运算符?理由就是,我们C++语⾔中已经给出的运算符(包括算数运算符和逻辑运算符)只是针对C++语⾔中已经给定的数据类型进⾏运算,假如我们想要对我们的⾃定义数据类型进⾏运算的话,则需要重载运算符,我们可以把重载运算符理解成对已有的运算符的⼀种重新定义。

⽐如:double a,b,c;a=1/3;b=1/2;c=a+b;printf("%lf",c);这段程序输出的肯定不是两个分数相加的结果。

这时候我们就可以重载运算符+。

⼆、重载运算符的实现语法格式如下(⾮常重要)<返回类型> operator <运算符符号>(<参数>){<定义>;}这⾥我们举⼀个例⼦。

在优先队列(priority_queue)中,存储的元素较⼤的会被放到堆顶。

如果存的是int或者string等类型还好办(因为他们本⾝就可以互相⽐较⼤⼩),如果是我们⾃定义的结构体类型,那就需要重载<运算符。

⽐如:struct node{int id;double x,y;}//定义结构体bool operator <(const node &a,const node &b){return a.x<b.x && a.y<b.y;}//重载运算符“<”注:这⾥的结构体保存了⼀个整型变量id,两个长浮点变量x,y,表⽰坐标。

这⾥的重载运算符先⽐横坐标后⽐纵坐标。

三、重载运算符的注意事项。

以下运算符不可重载:关系运算符"."成员指针运算符".*"作⽤域运算符"::"sizeof运算符三⽬运算符"?:"重载运算符限制在C++语⾔中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。

结构体重载运算符

结构体重载运算符
运算符重载是指在C++程序设计语言中,可以为现存的类型定义新的运算符的
功能。

运算符重载也就是给C++中的某些运算符功能上增加定义和改变其内部操作
以适应业务程序需求、提高程序开发效率而实现的技术。

运算符重载对于改善C++程序设计语言的结构表达和可读性都有着重要的作用。

它使得在C++程序设计过程中,可以利用运算符重载将复杂的算法编写简洁,更容
易理解,并且更有利于程序可维护性和可维护性。

一般来说,重载的运算符必须是类的成员函数,而且也不能对运算符的优先级
有改变,而改变其函数原型。

当某个运算符被重载时,它可以按照开发者的要求来处理数据。

例如,可能需要定义一个加法运算符“+”,但是此加法运算符可以处
理不同类型或参数的数据,以便在实际开发过程中更方便。

此外,要使用运算符重载,还需要遵循限制使用运算符的规则,例如,要使用
类中的成员函数定义运算符,且不能重载任何C++系统或类型操作符,因此必须时
刻注意自己的操作,以免搞砸整个运算符重载,对程序编写带来干扰。

总之,运算符重载的主要用途在于改善C++程序编写的优雅性和简洁性,以及
提高开发者使用程序设计语言的效率。

像一些复杂的运算符一样,重载运算符可以帮助程序员实现更有效、更简洁的算法,因此可以将难以理解和记忆的复杂混乱的算法变成一句简单的话。

运算符重载

CCS E
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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

方案二:重载成友员函数
class Rational { friend Rational operator+(const Rational &r1, const Rational &r2); friend Rational operator*(const Rational &r1 , const Rational &r2); friend bool operator<(const Rational &r1 , const Rational &r2) ; friend bool operator==(const Rational &r1 , const Rational &r2); friend bool operator>(const Rational &r1 , const Rational &r2) ; friend bool operator<=(const Rational &r1 , const Rational &r2); friend bool operator>=(const Rational &r1 , const Rational &r2); friend bool operator!=(const Rational &r1 , const Rational &r2) ;
扩充运算符的功能 增强了C++ 语言的可扩充性不是所有的运算符都能重载 重载不能改变运算符的优先级和结合性 重载不能改变运算符的操作数个数 不能创建新的运算符
可以重载的运算符
+ - * / % ^ &| ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- ->* , -> [] () new delete new[] delete[]
重载后有理数类的使用
int main() { Rational r1(1,6), r2(1,6), r3;
r3 = r1 + r2; r1.display(); cout << " + "; r2.display(); cout << " = "; r3.display(); cout << endl; r3 = r1 * r2; r1.display(); cout << " * "; r2.display(); cout << " = "; r3.display(); cout << endl; return 0; }
不能重载的运算符
. .* :: ?: sizeof
第11章 运算符重载
什么是运算符重载 运算符重载的方法 几个特殊的运算符的重载 自定义类型转换运算符 运算符重载实例
运算符重载的方法
运算符重载就是写一个函数解释某个运算符在 某个类中的含义
要使得系统能自动找到重载的这个函数,函数 名必须要体现出和某个被重载的运算符的联系。
函数实现
Rational Rational::operator+(const Rational &r1) const { Rational tmp;
tmp.num = num * r1.den + r1.num * den; tmp.den = den * r1.den; tmp.ReductFraction(); return tmp; }
第11章77 运算符重载
什么是运算符重载
使系统内置的运算符可以用于类类型 例如:+ 运算符能够实现2个对象间的加。
例如:类A的对象a1、a2、a3,希望: a3 = a1 + a2; 即:分别把对象a1和a2的各个数据成员值 对应相加,然后赋给对象a3。
问题的提出
把某些事交给系统去做,用户只要知道相 加就可
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; } 其他函数实现略
C++中规定,重载函数名为 operator@ 其中,@为要重载的运算符。如要重载“+”运
算符,该重载函数名为operator+。要重载赋值 运算符,函数名为operator=。
函数原型
运算符的重载不能改变运算符的运算对象数。因此,重载函 数的形式参数个数(包括成员函数的隐式指针this)与运算 符的运算对象数相同
运算符重载可以重载成成员函数也可以重载成全局函数实现。 重载成全局函数时,最好把此函数设为友员函数
如果作为类的成员函数,它的形式参数个数比运算符的运算 对象数少1。这是因为成员函数有一个隐含的参数this。在 C++中,把隐含参数this作为运算符的第一个参数。
当把一个一元运算符重载成成员函数时,该函数没有形式参 数。
bool Rational::operator>=(const Rational &r1) const { return num * r1.den >= den * r1.num; }
bool Rational::operator!=(const Rational &r1) const { return !(*this == r1);}
};
函数的实现
Rational operator+(const Rational &r1, const Rational &r2) { Rational tmp;
tmp.num = r1.num * r2.den + r2.num * r1.den; tmp.den = r1.den * r2.den; tmp.ReductFraction(); return tmp; }
把一个二元运算符重载成成员函数时,该函数只有一个形式 参数,就是右操作数,当前对象是左操作数。
重载实例
为rational类增加“+”和“*”以及比较的重 载函数,用以替换现有的add和multi函数
方案一:重载成成员函数
class Rational { private:
int num; int den; void ReductFraction(); public: Rational(int n = 0, int d = 1) { num = n; den = d;}
赋值运算符重载和拷贝构造函数
一般来讲,需要拷贝构造函数的类也需要 重载赋值运算符
定义对象时给对象赋初值调用的是拷贝构 造函数
程序的语句部分中的赋值语句调用的是赋 值运算符重载函数
几个特殊的运算符的重载
赋值运算符 下标运算符 函数调用运算符 ++和—运算符的重载 重载函数的原型设计考虑 输入输出运算符重载
bool Rational::operator<(const Rational &r1) const { return num * r1.den < den * r1.num; }
bool Rational::operator==(const Rational &r1) const { return num == r1.num && den == r1.den;}
会引起内存泄漏 使这两个数组的元素存放于同一块空间中
当这两个对象析构时,先析构的对象会释放 存储数组元素的空间。而当后一个对象析构 时,无法释放存放数组元素的空间
赋值运算符“=”的原型
赋值运算符只能重载成成员函数 函数原型:
X &X::operator=(const X &source) { // 赋值过程 }
private: int num; int den; void ReductFraction();
public: Rational(int n = 0, int d = 1) { num = n; den = d;} void display() { cout << num << '/' << den;}
bool Rational::operator>(const Rational &r1) const { return num * r1.den > den * r1.num; }
bool Rational::operator<=(const Rational &r1) const { return num * r1.den <= den * r1.num; }
Rational Rational::operator*(const Rational &r1) const { Rational tmp;
tmp.num = num * r1.num; tmp.den = den * r1.den; tmp.ReductFraction(); return tmp; }
以使得应用更加灵活。如果把加运算定义成全局函数,r是 有理数类的对象,则2+r是一个合法的表达式。
第11章 运算符重载
什么是运算符重载 运算符重载的方法 几个特殊的运算符的重载 自定义类型转换运算符 运算符重载实例
几个特殊的运算符的重载
相关文档
最新文档