作业3-运算符重载

合集下载

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

运算符重载

运算符重载

第八部分运算符重载第18章第18章运算符重载18.1 运算符重载的需要性1. 所谓运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型。

例18.1class A{public:A(int x) {a=x;}protected:int a;};A a(5),b(10),c;c=a+b; //错误,因+运算符不适合类对象,但我们可重载该运算符,使其适应类对象。

18.2 如何重载运算符1. 运算符重载是通过运算符重载函数完成的。

运算符重载函数可以是类的成员函数,也可以是类的友元函数。

2. 运算符重载函数定义格式。

(1)单目运算符重载函数定义类型 operator 单目运算符(参数) 函数体函数名(2)双目运算符重载函数定义类型 operator 双目运算符(参数1, 参数2) 函数体函数名(3)单目运算符重载函数调用operator 单目运算符(实参实参(3)单目运算符重载函数调用operator 双目运算符(实参1, 实参 1 双目运算符实参23.因成员函数有一个默认的参数this,故运算符重载函数是类的成员函数时,其参数可比格式中的参数少一个。

例18.2用友元函数对二维向量重载双目运算符+和单目运算符++。

#include<iostream.h>class vector{int x,y;public:vector();vector(int x1,int y1);void print();friend vector operator ++(vector& v1,int);// 单目运算符++重载函数原型friend vector operator +(vector& v1,vector& v2); // 双目运算符+重载函数原型};vector:: vector (){x=0;y=0;}vector:: vector (int x1,int y1) {x=x1;y=y1;}void vector::print(){cout<<"\n("<<x<<","<<y<<")";}vector operator ++(vector& v1,int){vector v2(v1.x,v1.y);v1.x++;v1.y++;return v2;}vector operator +( vector& v1,vector& v2){vector v0;v0.x=v1.x+v2.x;v0.y=v1.y+v2.y;return v0;}main(){vector v1(10,10);v1.print();vector v11;v11=v1++;//即v11=operator ++(v1,1);v1.print();v11.print();vector v2(20,20);(v1+v2).print();//即operator +(v1,v2).print();vector v3;v3=v1+v2;//即v3=operator +(v1,v2);v3.print();v3++.print();//即operator ++(v3,1).print();return 0;}(10,10)(11,11)(10,10)(31,31)(31,31)(31,31)例18.3用成员函数对二维向量重载双目运算符+和单目运算符++。

运算符重载

运算符重载

第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;}结果无疑是正确的,但调用方式不直观、太烦琐,使人感到很不方便。

运算符重载函数的两种主要方式

运算符重载函数的两种主要方式

运算符重载函数的两种主要方式
运算符重载是C++语言中的一种特性,它可以让用户定义类或结构体中的运算符的行为,以满足用户的需求。

换句话说,运算符重载就是在类或结构体中定义新的运算符,以替代原有的运算符。

一般来说,运算符重载通过两种主要方式实现:类内重载和类外重载。

类内重载是将运算符重载函数定义在类内部,该函数的声明必须使用operator关键字。

这种方式的优点是可以使用类的受保护成员。

类内重载的运算符函数有一个或两个参数,参数的类型是类的类型,或者是类的对象。

类外重载是在类外定义运算符重载函数,该函数的声明仍然要使用operator关键字,但参数的类型是左操作数和右操作数的类型。

类外重载的运算符函数有两个参数,参数的类型是左操作数和右操作数的类型。

类外重载的优点是可以使用不同类型的操作数,而类内重载的运算符函数只能使用类的类型或类的对象作为参数。

使用运算符重载有很多优点,可以提高程序的可读性,使代码更加容易理解。

此外,运算符重载还可以减少代码量,减少函数调用的次数,以及提高程序的效率。

总之,运算符重载是一种有效的编程技巧,可以提高程序的可读性,提高程序的效率,增加程序的可维护性,减少代码量。

使用运算符重载,可以使用户能够更加熟练地使用C++语言,也可以更好地保护类的封装性。

国家二级C%2b%2b机试(运算符重载)模拟试卷3.doc

国家二级C%2b%2b机试(运算符重载)模拟试卷3.doc

控制面板试卷遒分:分试题数量:答题120分-钟一剩余时间:调整字号:12 14 16 1820调整背景:国家二级C++机试(运算符重载)模拟试卷3全部题型1.选择题选择题1.运算符重载是对已有的运算符赋予多重含义,因此()。

A.可以对基本类型(如int类型)的数据,重新定义“+”运算符的含义□ B.可以改变一个己有运算符的优先级和操作数个数C.只能重载C++中已经有的运算符,不能定义新运算符D. C++中己经有的所有运算符都可以重载正确答案:c解析:此题考查的是运算符重载。

运算符重载是针对C++语言原有的运算符进行的,并不能创造新的运算符。

2.通过运算符重载,可以改变运算符原有的()。

A.操作数类型B.操作数个数C.优先级D.结合性正确答案:A解析:此题考查的是运算符重载。

运算符重载具有保持其原有的操作数个数、优先级、语法结构和结合性不变的特性。

故本题选项A正确。

答题卡1A B C D2 A B C D3 A B C D4 A B C D5 A B C D6A B C D7 A B C p8 A B C D9 A B C D WA B C D11 A B CD12A BCD13A BCD14A B C D -----15 A B C D 16A B C D 17A BCD18A B C D 19A BCD20A BCD21A BCD 22 A B C D3.下列关于运算符重载的描述中,正确的是()。

A.运算符重载为成员函数时,若参数表中无参数,重载的是一元运算符B.•元运算符只能作为成员函数重载C.二元运算符重载为非成员函数时,参数表中有一个参数D.C++中可以重载所有的运算符正确答案:A解析:此题考查的是运算符的重载。

运算符重载为成员函数时,形参个数一般为运算符元数减1;重载为非成员函数时,形参个数一般和运算符元数相等。

所以二元运算符重载为非成员函数时,参数表中应有两个参数,C选项错误:运算符重载为成员函数,若参数表中无参数,重载的是一元运算符,选项A 正确:一元运算符中,“・”(取负)、"++”、"・・”等均可重载为成员函数:C++ 语言中,”、*”、"・>*"、":: ”、“?:”五个运算符不能重载。

作业3-运算符重载

作业3-运算符重载

作业3
1.定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。

参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意。

例如:c1+c2,i+c1,c1+i均合法(设i为整数,c1,c2为复数)。

编程序,分别求两个复数之和、整数和复数之和。

2.有两个矩阵a和b,均为2行3列。

求两个矩阵之和。

重载运算符“+”,使之能用于矩阵相加。

如:c=a+b。

3.在第2题的基础上,重载流插入运算符“<<”和流提取运算符“>>”,使之能用于该矩阵的输入和输出。

4.请编写程序,处理一个复数与一个double数相加的运算,结果存放在一个double型的变量d1中,输出d1的值,再以复数形式输出此值。

定义Complex(复数)类,在成员函数中包含重载类型转换运算符:operator double( ){return real;}
1。

简述运算符重载的规则。

简述运算符重载的规则。

简述运算符重载的规则。

运算符重载是指可以为自定义的类类型或枚举类型定义新的含义和功能。


C++中,运算符重载遵循以下一般规则:
1. 运算符重载必须至少有一个操作数是用户自定义的类类型或枚举类型的对象,否则将无法重载。

2. 运算符重载可以作为成员函数或非成员函数来实现。

3. 对于成员函数的运算符重载,操作数的数量为运算符的操作数减去1。

例如,重载双目运算符时(如+、-、*等),成员函数需要接受一个参数,用于表示另一个操作数。

4. 对于非成员函数的运算符重载,所有操作数都作为参数传递给函数。

可以通过将重载运算符函数声明为友元函数来访问类的私有成员。

5. 对于重载一元运算符(如++、),如果是成员函数,则返回一个修改后的对象;如果是非成员函数,则返回一个新的对象。

6. 对于重载二元运算符(如+、-、*等),如果是成员函数,则一个对象被修改,另一个对象不变;如果是非成员函数,则返回一个新的对象。

7. 运算符重载不能改变原有运算符的优先顺序和结合性。

8. 运算符重载遵循函数重载的规则,即可以根据参数类型和参数数量进行重载,实现不同的功能。

需要注意的是,运算符重载应该遵循语义上的合理性并不滥用。

运算符重载

运算符重载
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指针自由地访问本类 的数据成员, 的数据成员,因此可以少写一个函数 的参数。 的参数。但必须要求运算表达式第一 个参数(即运算符左侧的操作数) 个参数(即运算符左侧的操作数)是一 个类对象, 个类对象,而且与运算符函数的类型 相同。 相同。因为必须通过类的对象去调用 该类的成员函数,而且只有运算符重 该类的成员函数, 载函数返回值与该对象同类型, 载函数返回值与该对象同类型,运算 结果才有意义。 结果才有意义。

运算符重载

运算符重载

运算符重载运算符重载可以通过定义类的成员函数和友元全局函数实现运算符重载可以看做是一个函数重载,特殊之处是函数名有差别,函数名是“operator”重载的规则:①只能重载已有的运算符而不能创造新的运算符②重载不能改变优先级和结合型及操作数个数<硬性要求>③重载的功能应与运算符原有功能相似④有些运算符不能重载: . .* :: ?:Complex c = a.operator+(b); //显示Complex c = a + b; //隐示用成员函数重载运算时,该运算符的左操作数必须是本类对象,当成员函数作为重载运算符时,成员函数不能是static类型(静态成员函数)//例子://尽量用成员函数重载单目运算符#include <iostream>using namespace std;class Complex{public:Complex(double aReal = 0,double aImage = 0);double getReal() const; //为只读对象创建接口double getImage() const;Complex operator+(const Complex &aRef) const; Complex operator-(const Complex &aRef) const; Complex operator++(); //前缀Complex operator++(int); //后缀Complex operator--();Complex operator--(int);private:double m_aReal;double m_aImage;};Complex::Complex(double aReal,double aImage){ m_aReal = aReal;m_aImage = aImage;}double Complex::getReal() const{return m_aReal;}double Complex::getImage() const{return m_aImage;}Complex Complex::operator +(const Complex &aRef) const{double real = m_aReal + aRef.m_aReal;double image = m_aImage + aRef.m_aImage;return Complex(real,image);}Complex Complex::operator ++(int){ //a++后缀Complex temp(*this);m_aReal++;m_aImage++;return temp;}Complex Complex::operator ++(){ //++a前缀m_aReal++;m_aImage++;return Complex(*this);}Complex Complex::operator - (const Complex &aRef) const{ double real = m_aReal - aRef.m_aReal;double image = m_aImage - aRef.m_aImage;return Complex(real,image);}Complex Complex::operator --(){ //--a前缀m_aReal--;m_aImage--;return Complex(*this);}Complex Complex::operator –(int){ //a--后缀Complex temp(*this);m_aReal--;m_aImage--;return temp;}int main(){Complex a(2,3);Complex c=a++;cout << c.getReal() << " " <<c.getImage() << endl;//2 3cout << a.getReal() << " " <<a.getImage() << endl;//3 4c = a+c;cout << c.getReal() << " " <<c.getImage() << endl;//5 7c = a-c;cout << c.getReal() << " " <<c.getImage() << endl;//-2 -3Complex d = --c;cout << d.getReal() << " " << d.getImage() << endl;//-3 -4}双目运算符<< 和>> 的重载//仅能使用友元函数重载输入和输出运算符?左操作数不是本类对象#include<iostream>using namespace std;class Complex{private:double m_dReal;double m_dImag;public:Complex(double ireal=0,double image=0):m_dReal(ireal),m_dImag(image){}friend istream &operator >> (istream &in,Complex &arg){ in >> arg.m_dReal;in >> arg.m_dImag;return in;}friend ostream &operator << (ostream &out,const Complex &arg){ out << arg.m_dReal << " ";out << arg.m_dImag;return out;}};int main(){Complex a(5.3,2.5);cin >> a;cout << a;}//赋值运算符的重载//赋值运算符要求第一个运算数必须为本类对象,因此只能用成员函数重载当构造函数申请堆区内存空间时,需要定义:①拷贝构造函数②析构函数③赋值运算符重载//string函数运算符重载#include<iostream>#include<string.h>#include<stdlib.h>using namespace std;class String{public:String(const char* aStr="");String(const String & aRef); //拷贝构造函数int Size();String &operator=(const String &aRef);//赋值运算符重载friend ostream &operator<<(ostream &out,String &aRef);//输入运算符重载friend istream &operator>>(istream &in,String &aRef);//输出运算符重载char & operator [](const int aIndex); //下标运算符的重载~String(); //析构函数private:char * m_pStr;};String::String(const char *aStr){m_pStr = new char[strlen(aStr)+1];//保留结束符位置'\0'strcpy(m_pStr,aStr);}String::~String(){delete []m_pStr;}String::String(const String & aRef){// 拷贝构造函数实现深拷贝//自赋值操作需要吗?不需要=>拷贝构造函数的调用m_pStr = new char[strlen(aRef.m_pStr)+1];strcpy(m_pStr,aRef.m_pStr);}String &String::operator=(const String &aRef){ //赋值运算符重载if(this != &aRef){//防止自赋值操作=> a=a;delete []m_pStr; //防止内存泄漏m_pStr = new char[strlen(aRef.m_pStr)+1];strcpy(m_pStr,aRef.m_pStr);}return *this;}int String::Size(){return strlen(m_pStr);}ostream &operator<<(ostream &out,String &aRef){ out << aRef.m_pStr;return out;}istream &operator>>(istream &in,String &aRef){in >> aRef.m_pStr;return in;}char &String::operator [](const int aIndex){ //下标运算符重载if(aIndex >= strlen(m_pStr) || aIndex < 0){ exit(-1);}return m_pStr[aIndex];}int main(){String a("Hello");String b(a);//cin >> a;a[0] = 'P';cout << a << endl;String c;c = a;cout << c << endl;}//main。

简述运算符重载的规则。

简述运算符重载的规则。

简述运算符重载的规则。

篇一:运算符重载是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. 逻辑运算符重载逻辑运算符包括条件运算符和逻辑非运算符。

每个逻辑运算符都有一组默认的行为,可以通过运算符重载来自定义它们的行为。

运算符重载

运算符重载

运算符重载所谓重载,就是重新赋予新的含义,函数重载就是对一个已有的函数赋予新的含义,使之实现新功能。运算符的重载主要存在两种形式,一种是作为类的成员函数进行使用,另一种则是作为类的友元函数进行使用。

运算符的重载的形式为:返回类型operator 运算符符号(参数说明){//函数体的内部实现}例如,能否用“+”号进行两个复数的相加,在C++中不能在程序中直接用运算符“+”对复数进行相加运算,用户必须自己设法实现复数相加。

例如用户可以通过定义一个专门的函数来实现复数相加。

/*实现复数类中的运算符重载定义一个复数类重载运算符+、-、*、/,使之能用于复数的加减乘除。

方案一:使用类的成员函数完成运算符的重载;*/#include<iostream>using namespace std;class Complex{private:double real;double imag;public:Complex(){real = 0 ; imag = 0 ;}Complex(double r,double i){real = r ; imag = i ;}Complex operator+(Complex &c2);Complex operator-(Complex &c2);Complex operator*(Complex &c2);Complex operator/(Complex &c2);void display();};//下面定义成员函数Complex Complex::operator+(Complex &c2) //定义重载运算符”+“的函数{return Complex(this->real+c2.real , this->imag+c2.imag); //此处this->real就是c1.real}Complex Complex::operator-(Complex &c2)//定义重载运算符”-“的函数{return Complex(this->real-c2.real , this->imag-c2.imag); //此处this->real就是c1.real}Complex Complex::operator*(Complex &c2){return Complex(this->real*c2.real , this->imag*c2.imag); //此处this->real就是c1.real}Complex Complex::operator/(Complex &c2){Complex c;c.real = (real*c2.real + imag*c2.imag)/(c2.real*c2.real+c2.imag*c2.imag);c.imag = (-real*c2.imag + imag*c2.real)/(c2.real*c2.real+c2.imag*c2.imag);return c;}void Complex::display(){cout<<"("<<real<<","<<imag<<"i)"<<endl;}int main(void){Complex c1(3,4),c2(5,-10),c3;cout<<"c1=";c1.display();cout<<"c2=";c2.display();c3=c1+c2; // 此处相当于非重载运算符函数中的“c3=plex_add(c2)//将运算符+重载为类的成员函数后,编译系统会将程序中的表达式c1+c2解释为:c1.operator+(c2)即以c2为实参调用c1的运算符重载函数operator+(Complex&c2),operator+是类的一个函数名cout<<"c1+c2=";c3.display();c3=c1-c2;cout<<"c1-c2=";c3.display();c3=c1*c2;cout<<"c1*c2=";c3.display();c3=c1/c2;cout<<"c1/c2=";c3.display();return 0;}运算符重载运算符的运算规则①运算符重载函数也是函数,重载的运算符不会改变运算符的优先级、结合型和参数的个数。

Python编程基础之运算符重载详解

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
运⾏程序,查看结果
如果两个数组长度不相等,那么就会抛出异常
总结
本篇⽂章就到这⾥了,希望能够给你带来帮助,也希望您能够多多关注的更多内容!。

《运算符重载》PPT课件_OK

《运算符重载》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; }

运算符重载——精选推荐

运算符重载——精选推荐

运算符重载运算符重载学习运算符重载,让运算符能做⼀些原来做不了的事情,⽅便它的使⽤⼀、运算符重载的概念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可以是任意整数。

运算符重载解读

运算符重载解读

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

运算符重载详解

运算符重载详解

运算符重载详解1.运算符重载定义:C++中预定义的运算符的操作对象只能是基本数据类型。

但实际上,对于许多⽤户⾃定义类型(例如类),也需要类似的运算操作。

这时就必须在C++中重新定义这些运算符,赋予已有运算符新的功能,使它能够⽤于特定类型执⾏特定的操作。

运算符重载的实质是函数重载,它提供了C++的可扩展性,也是C++最吸引⼈的特性之⼀。

运算符重载是通过创建运算符函数实现的,运算符函数定义了重载的运算符将要进⾏的操作。

运算符函数的定义与其他函数的定义类似,惟⼀的区别是运算符函数的函数名是由关键字operator和其后要重载的运算符符号构成的。

运算符函数定义的⼀般格式如下:<返回类型说明符> operator <运算符符号>(<参数表>){<函数体>} 2.运算符重载时要遵循以下规则:(1) 除了类属关系运算符"."、成员指针运算符".*"、作⽤域运算符"::"、sizeof运算符和三⽬运算符"?:"以外,C++中的所有运算符都可以重载。

(2) 重载运算符限制在C++语⾔中已有的运算符范围内的允许重载的运算符之中,不能创建新的运算符。

(3) 运算符重载实质上是函数重载,因此编译程序对运算符重载的选择,遵循函数重载的选择原则。

(4) 重载之后的运算符不能改变运算符的优先级和结合性,也不能改变运算符操作数的个数及语法结构。

(5) 运算符重载不能改变该运算符⽤于内部类型对象的含义。

它只能和⽤户⾃定义类型的对象⼀起使⽤,或者⽤于⽤户⾃定义类型的对象和内部类型的对象混合使⽤时。

(6) 运算符重载是针对新类型数据的实际需要对原有运算符进⾏的适当的改造,重载的功能应当与原有功能相类似,避免没有⽬的地使⽤重载运算符。

(7)重载运算符的函数不能有默认的参数,否则就改变了运算符的参数个数,与前⾯第3点相⽭盾了;(8)重载的运算符只能是⽤户⾃定义类型,否则就不是重载⽽是改变了现有的C++标准数据类型的运算符的规则了,会引会天下⼤乱的;(9)⽤户⾃定义类的运算符⼀般都必须重载后⽅可使⽤,但两个例外,运算符“=”和“&”不必⽤户重载;(10)运算符重载可以通过成员函数的形式,也可是通过友元函数,⾮成员⾮友元的普通函数。

第3章 运算符重载

第3章 运算符重载
11
3.2 重载成员函数-实例-3/3
void complex::display() { cout<<"("<<m_real<<","<<m_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="; c1=(5,4) c3.display(); c2=(2,10) c3=c1+c2; //使用重载运算符完成复数加法 c3=c1-c2=(3,-6) cout<<"c3=c1+c2="; c3.display(); c3=c1+c2=(7,14) }
运算符 双目运 算符@ 前置单目@ @ oprd 后置单目@ oprd @ operator @(oprd ) operator @(oprd,0 ) 使用形式 oprd1 @ oprd2 等价式 operator @(oprd1,oprd2 )
15
3.3 重载友元函数-使用
• 如果一个运算符想用某个基本类型的数据调用,它就必须
10
3.2 重载成员函数-实例-2/3
const complex complex::operator +(complex c2) //重载函数实现 { complex c; 如何创建的? c.m_real = c2.m_real+m_real; c.m_imag = c2.m_imag+m_imag; 这是个什么式子? 做了件什么事? return complex(c.m_real,c.m_imag); 是否可以简化? } const complex complex::operator -(complex c2) //重载函数实现 { complex c; c.m_real = m_real-c2.m_real; c.m_imag = m_imag-c2.m_imag; return c; }
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

作业3
1.定义一个复数类Complex,重载运算符“+”,使之能用于复数的加法运算。

参加运算的两个运算量可以都是类对象,也可以其中有一个是整数,顺序任意。

例如:c1+c2,i+c1,c1+i均合法(设i为整数,c1,c2为复数)。

编程序,分别求两个复数之和、整数和复数之和。

2.有两个矩阵a和b,均为2行3列。

求两个矩阵之和。

重载运算符“+”,使之能用于矩阵相加。

如:c=a+b。

3.在第2题的基础上,重载流插入运算符“<<”和流提取运算符“>>”,使之能用于该矩阵的输入和输出。

4.请编写程序,处理一个复数与一个double数相加的运算,结果存放在一个double型的变量d1中,输出d1的值,再以复数形式输出此值。

定义Complex(复数)类,在成员函数中包含重载类型转换运算符:operator double( ){return real;}
5.。

相关文档
最新文档