运算符重载
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 ) ;
qml 重载运算符 -回复

qml 重载运算符-回复QML重载运算符在QML语言中,除了可以使用内置的运算符,开发者还有机会通过重载运算符来自定义自己的操作符功能。
重载运算符可以为开发者提供更多的灵活性和方便性,使得代码更加可读和简洁。
本文将详细介绍如何在QML 中重载运算符,并提供一些示例来帮助读者更好地理解。
1. 什么是运算符重载?运算符重载(Operator Overloading)是指那些在特定的对象或结构上定义运算符行为的技术。
通过重载运算符,可以在不同类型的对象之间执行自定义的操作。
在QML中,可以使用关键字`operator`来重载运算符。
2. 为什么要重载运算符?在开发过程中,为了使代码更加简洁和可读,有时候需要为自定义类型或内置类型提供一些自定义的操作。
而重载运算符可以提供这种功能,使得代码更加直观和易于理解。
此外,通过重载运算符,还可以实现自定义类型之间的运算和交互,提高代码的可复用性。
3. 如何重载运算符?在QML中,重载运算符的语法如下:property<parameter> object.operator<operator> (parameter)在上述语法中,`object`是需要重载运算符的对象,`operator`是要重载的运算符,`parameter`是运算符的参数。
在实现重载运算符时,需要注意以下几点:- 重载运算符的行为应该是与标准运算符相似的,以保持代码的一致性和可预测性。
- 重载运算符可以应用于自定义类型以及内置类型,但不能应用于已经有定义的类型。
- 重载运算符通常被定义为返回值的函数。
4. 示例:自定义向量类型的加法运算接下来,我们将使用一个例子来演示如何重载运算符。
假设有一个名为`Vector`的自定义类型,我们想要为它定义加法运算符的行为。
以下是我们的示例代码:import QtQuick 2.0Item {property real x: 0.0property real y: 0.0operator + (vector) {var result = Vector();result.x = this.x + vector.x;result.y = this.y + vector.y;return result;}}在上述代码中,我们通过重载`+`运算符来定义了向量类型之间的加法。
运算符重载

void complex::print( ) { if (imag==0) cout<<real<<endl; else if(imag>0) cout<<real<<"+"<<imag<<"i\n"; else cout<<real<<imag<<"i\n"; } complex operator -(complex obj) { complex temp; temp. real= -obj.real ; temp. imag= -obj.imag; return temp; }
10
void main( ) { complex com1(2.3,4.6),com2(3.6,2.8),result; cout<<"complex com1 and com2 orderly:\n"; com1.print( ); com2.print( ); result=com1+com2; cout<<"com1+com2="; result.print( ); result=com1-com2; cout<<"com1-com2="; result.print( ); result=com1*com2; cout<<"com1*com2="; result.print( ); result=com1/com2; cout<<"com1/com2="; result.print( ); }
2、双目运算符的重载
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++的标准类型;运算符重载函数可以是类的成员函数,也可以是类的友员函数,也可以使普通函数。
运算符重载

1、多态性的基本概念2、派生类对象替换基类对象3、虚函数的定义4、抽象类的定义5、宠物类的设计6、运算符重载7、日期类对象判断大小8、分数类对象运算符重载☐运算符重载指赋予运算符新的操作功能,主要用于对类的对象的操作☐运算符+意味着多少对象类型的加法呢?☐还可以定义新的对象类型加法☐运算符重载定义形式:<类型><类名>::operator<操作符>(<参数表>){函数体}☐首先定义虚数类☐虚数可以描述为:a+bi☐a与b看成实数,定义成double类型☐成员函数除了构造与析构外,还有:☐输出虚数、修改虚数、得到实部a、得到虚部b ☐相加+、判相等==#include <iostream>using namespace std;class Complex{private:double real, imag;public:Complex(double r = 0, double i = 0): real(r), imag(i){ }double Real(){return real;}double Imag(){return imag;}Complex operator +(Complex&);Complex operator +(double);bool operator ==(Complex);~Complex(){ };Complex Complex::operator +(Complex &c)// 重载运算符+,两边是虚数对象{Complex temp;temp.real = real+c.real;temp.imag = imag+c.imag;return temp;}Complex Complex::operator +(double d)// 重载运算符+,左边是虚数对象,右边是双精度数{Complex temp;temp.real = real+d;temp.imag=imag;return temp;}bool Complex::operator ==(Complex c)// 重载运算符=={if (real == c.real && imag == c.imag)return true;elseint main(){Complex c1(3,4),c2(5,6),c3;cout << "C1 = " << c1.Real() << "+j" << c1.Imag() << endl;cout << "C2 = " << c2.Real() << "+j" << c2.Imag() << endl;c3 = c1+c2;cout << "C3 = " << c3.Real() << "+j" << c3.Imag() << endl;c3 = c3+6.5;cout << "C3 + 6.5 = " << c3.Real() << "+j" << c3.Imag() << endl;if ( c1==c2 )cout<<“两个复数相等”;elsecout<<“两个复数不相等”;return 0;☐运算符++分前置运算符和后置运算符☐例如: ++Y与Y++☐前置运算符定义Complex Complex::operator ++ () {real+=1;return *this;}☐后置运算符定义Complex Complex::operator ++ (int) {real+=1;return *this;}。
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; ▪}
c++运算符重载实验心得

c++运算符重载实验心得
在C++中,运算符可以被重载以在自定义数据类型上执行特定操作。
在这个实验中,我学习了如何使用C++中的运算符重载,以及如何实现对自定义数据类型的专门操作。
以下是我的一些心得体会:
1. 运算符重载可以使代码更加简洁和易读。
通过重载运算符,我们可以使用类似于内置类型的语法来操作自定义类型,这样代码更加容易理解和维护。
2. 每个运算符都有其特定的重载方式。
例如,重载加法运算符可以使用成员函数或自由函数来实现,但重载等于运算符只能使用成员函数来实现。
3. 重载运算符时需要注意参数和返回值。
参数通常是类的对象或引用,而返回值可以是任何类型,包括类的对象、指针或引用。
4. 运算符重载还可以使用友元函数来实现,这样可以访问类的私有成员。
但是,应该谨慎使用友元函数,因为它们可能破坏类的封装性。
5. 在重载运算符时,应该遵循一些常规规则。
例如,对于双目运算
符,应该使用const关键字来保证左右操作数的不可变性;对于单目运算符,应该使用++或--操作符,并将其实现为成员函数。
总之,通过学习C++运算符重载,我更好地理解了类的封装性和抽象性,以及如何在自定义类型上执行特定操作。
这将对我的日后编程工作带来很大的帮助。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第4章运算符重载4.1 什么是运算符重载所谓重载,就是重新赋予新的含义。
函数重载就是对一个已有的函数赋予新的含义,使之实现新功能。
运算符也可以重载。
实际上,我们已经在不知不觉之中使用了运算符重载。
如:+可以对int、float、double的数据进行加法运算。
现在要讨论的问题是:用户能否根据自己的需要对C++已提供的运算符进行重载,赋予它们新的含义,使之一名多用。
譬如,能否用“+”号进行两个复数、两个点的相加。
在C++中不能在程序中直接用运算符“+”对复数进行相加运算。
用户必须自己设法实现复数相加。
例如用户可以通过定义一个专门的函数来实现复数相加。
见下例。
//例4.1 通过函数来实现复数相加。
#include <iostream>using namespace std;class Complex{public:Complex(){real=0;imag=0;} //构造函数Complex(double r,double i){real=r;imag=i;} //构造函数重载Complex complex_add(Complex &c2); //声明复数相加的函数void display(); //声明输出函数private:double real, imag;};Complex Complex::complex_add(Complex &c2){ Complex c;c.real=real+c2.real;c.imag=imag+c2.imag;return c;//以上可简写为:return Complex(real+c2.real,imag+c2.imag);}void Complex::display(){ cout<<"("<<real<<","<<imag<<"i)"<<endl;}int main(){ Complex c1(3,4),c2(5,-10),c3;c3=plex_add(c2);cout<<"c1="; c1.display();cout<<"c2="; c2.display();cout<<"c1+c2="; c3.display();return 0;}结果无疑是正确的,但调用方式不直观、太烦琐,使人感到很不方便。
能否也和整数的加法运算一样,直接用加号“+”来实现复数运算呢?如c3=c1+c2;,编译系统就会自动完成c1和c2两个复数相加的运算。
如果能做到,就为对象的运算提供了很大的方便。
这就需要对运算符“+”进行重载定义。
我们来想一下,一个整数加a+b,其实它的操作就是函数形式add(a,b)。
而写成a+b的形式更简单通俗而已。
所以我们对操作符也能像进行函数那样的定义。
思考:上例是用成员函数来实现的,那么用其它的函数形式能实现吗?//例:通过友元函数来实现复数相加。
#include <iostream>using namespace std;class Complex{public:Complex(){real=0;imag=0;} //构造函数Complex(double r,double i){real=r;imag=i;} //构造函数重载friend Complex complex_add(Complex &c1,Complex &c2);//声明复数相加的函数void display(); //声明输出函数private:double real, imag;};Complex complex_add(Complex &c1,Complex &c2){ Complex c;c.real=c1.real+c2.real;c.imag=c1.imag+c2.imag;return c;//以上可简写为:return Complex(real+c2.real,imag+c2.imag);}void Complex::display(){ cout<<"("<<real<<","<<imag<<"i)"<<endl;}int main(){ Complex c1(3,4),c2(5,-10),c3;c3=complex_add(c1,c2);acout<<"c1="; c1.display();cout<<"c2="; c2.display();cout<<"c1+c2="; c3.display();return 0;}通过普通函数怎么实现呢?4.2 运算符重载的方法运算符重载的方法是定义一个重载运算符的函数,在需要执行被重载的运算符时,系统就自动调用该函数,以实现相应的运算。
也就是说,运算符重载是通过定义函数实现的。
运算符重载实质上是函数的重载。
重载运算符的函数一般格式如下:函数类型operator 运算符名称(形参表列){ 对运算符的重载处理}例如,想将“+”用于Complex类(复数)的加法运算,函数可以是这样的:Complex operater+ (Complex& c1,Complex& c2);在定义了重载运算符的函数后,可以说:函数operator+重载了运算符+。
可以在例4.1程序的基础上重载运算符“+”,使之用于复数相加。
//例4.2 重载运算符“+”#include <iostream>using namespace std;class Complex{public:Complex(){real=0;imag=0;}Complex(double r,double i){real=r;imag=i;}Complex operator + (Complex &c2);void display();private:double real;double imag;};Complex Complex::operator + (Complex &c2){ Complex c;c.real=real+c2.real;c.imag=imag+c2.imag;return c;}//或简写为:{return Complex(real+c2.real,imag+c2.imag);}void Complex::display(){cout<<"("<<real<<","<<imag<<"i)"<<endl;}int main(){Complex c1(3,4),c2(5,-10),c3;c3=c1+c2; //+重载定义后可以直接用+cout<<"c1="; c1.display();cout<<"c2="; c2.display();cout<<"c1+c2="; c3.display();return 0;}请比较例4.1和例4.2,只有两处不同:●在例4.2中以operator+函数取代了例4.1中的complex_add函数,而且只是函数名不同,函数体和函数返回值的类型都是相同的。
●在main函数中,以“c3=c1+c2;”取代了例10.1中的“c3=plex_add(c2);”。
在将运算符+重载为类的成员函数后,C++编译系统将程序中的表达式c1+c2解释c1.operator+(c2)其中c1和c2是Complex类的对象,即以c2为实参调用c1的运算符重载函数operator+(Complex &c2),进行求值,得到两个复数之和。
虽然重载运算符所实现的功能完全可以用函数实现,但是使用运算符重载能使用户程序易于编写、阅读和维护。
在实际工作中,类的声明和类的使用往往是分离的。
假如在声明Complex类时,对运算符+,-,*,/都进行了重载,那么使用这个类的用户在编程时可以完全不考虑函数是怎么实现的,放心大胆地直接使用+,-,*,/进行复数的运算即可,十分方便。
c1+c2就相当于c1.operator+(c2),c1+c2的书写形式更加人性化。
4.3 重载运算符的规则重载运算符的规则如下:1、C++不允许用户自己创建新的运算符,只能对已有的C++运算符进行重载。
2、操作个数不变、优先级不变、结合性不变3、不能有默认的参数4、重载运算符必须和用户定义的对象一起使用,其参数至少应有一个是类对象或类对象的引用。
也就是说参数不能全是C++的标准类型,以防用户改变了原标准类型的运算性质。
5、重载后的操作符的新意思要与原意一致。
6、基本规则(有些规则在后面的实例中会讲到)1)一元操作符可以是不带参数的成员函数或带一个参数的非成员函数。
2)二元操作符可以是带一个参数的成员函数或带两个参数的非成员函数。
3)operator=、operator[]、operator()、operator->只能定义为成员函数。
4)operator->的返回值必须是一个指针或能使用->的对象。
5)重载operator++ 和operator-- 时带一个int 参数表示后缀,不带参数表示前缀。
6)除operator new 和operator delete 外,重载的操作符参数中至少要有一个自定义数据类型。
4.4 运算符重载函数作为类成员函数和友元函数在我们前面举的实例中,“+”是双目运算,但我们只看到一个参数。
那是因为重载函数是类中的成员函数,有一个参数是隐含的,运算符函数是用this指针隐式地访问类对象的成员。
运算符重载函数除了可以作为类的成员函数,还可以是非成员函数。
//例4.3 +重载,重载函数不作为成员函数,而是作为Complex的友员函数#include <iostream.h>//VC++没有完全实现C++标准,不带后缀.h的头文件不支持操作符重载为友元函数,//所以这里要加上.h,并删去使用名空间那句话。
class Complex{public:Complex(){real=0;imag=0;}Complex(double r){real=r;imag=0;}Complex(double r,double i){real=r;imag=i;}friend Complex operator+ (Complex &c1,Complex &c2);void display();private:double real;double imag;};Complex operator+ (Complex &c1,Complex &c2){return Complex(c1.real+c2.real, c1.imag+c2.imag);}void Complex::display(){cout<<"("<<real<<","<<imag<<"i)"<<endl;}int main(){Complex c1(3,4),c2(5,-10),c3;c3=c1+c2;cout<<"c1="; c1.display();cout<<"c2="; c2.display();cout<<"c1+c2="; c3.display();return 0;}与例4.2相比较,只作了一处改动,将运算符函数不作为成员函数,而把它放在类外,在Complex类中声明它为友元函数。