4.5 运算符重载
运算符重载概念:利用operator
对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
本质:
-
提供一个
operator 运算符()
函数,使得A operator 运算符(B)
的形式可以化简为A 运算符 B
的形式
4.5.1 加号/减号运算符重载
作用:实现两个自定义数据类型相加的运算
示例1
//成员函数实现 + / -号运算符重载
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class point{
public:
int x,y;
point(){}
point(int a,int b):x(a),y(b) {}
point operator+(const point p){ //成员函数实现 + 号运算符重载
point t;
t.x=this->x+p.x;
t.y=this->y+p.y;
return t;
}
point operator-(const point p){ //成员函数实现 - 号运算符重载
point t;
t.x=this->x-p.x;
t.y=this->y-p.y;
return t;
}
};
int main(){
point p1(1,1);
point p2(2,2);
point p3=p2+p1;
cout<<p3.x<<" "<<p3.y<<endl;
p3=p2-p1;
cout<<p3.x<<" "<<p3.y<<endl;
return 0;
}
示例2
//全局函数实现 + / -号运算符重载
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class point{
public:
int x,y;
point(){}
point(int a,int b):x(a),y(b){}
};
point operator+(const point &p1,const point &p2){ //全局函数实现 + 号运算符重载
point t;
t.x=p1.x+p2.x;
t.y=p1.y+p2.y;
return t;
}
point operator-(const point &p1,const point &p2){ //全局函数实现 - 号运算符重载
point t;
t.x=p1.x-p2.x;
t.y=p1.y-p2.y;
return t;
}
int main(){
point p1(1,1);
point p2(2,2);
point p3=p1+p2;
cout<<p3.x<<" "<<p3.y<<endl;
p3=p2-p1;
cout<<p3.x<<" "<<p3.y<<endl;
return 0;
}
总结
-
对于内置的数据类型的表达式的的运算符是不可能改变的
-
不要滥用运算符重载
4.5.2 左移运算符重载
作用:可以输出自定义数据类型
注意 :一般使用全局函数实现
示例
//全局函数实现左移重载
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class point{
public:
int x,y;
point(){}
point(int a,int b):x(a),y(b){}
};
//ostream对象只能有一个
ostream& operator<<(ostream &cout,point &p){
cout<<p.x<<" "<<p.y<<endl;
return cout;
}
int main(){
point p1(1,1);
cout<<p1<<"链式输出"<<endl;
return 0;
}
4.5.3 递增运算符重载
作用: 通过重载递增运算符,实现自己的整型数据
示例
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class point{
public:
int x,y;
point(){}
point(int a,int b):x(a),y(b){}
//前置递增
point& operator++(){
this->x++;
this->y++;
return *this;
}
//后置递增
point& operator++(int){ //int用于占位
this->x++;
this->y++;
return *this;
}
};
int main(){
point p1(1,1);
p1++;
++p1;
cout<<p1.x<<" "<<p1.y<<endl;
return 0;
}
4.5.4 赋值运算符重载
C++
编译器至少给一个类添加4个函数
-
默认构造函数(无参,函数体为空)
-
默认析构函数(无参,函数体为空)
-
默认拷贝构造函数,对属性进行值拷贝
-
赋值运算符
operator=
, 对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
示例:
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class point{
public:
int *x,*y; //开辟到堆区
point(){}
point(int a,int b){
x=new int(a); //将数据开辟到堆区
y=new int(b);
}
//重载赋值运算符
point& operator=(point &p){
if(this->x!=NULL){
delete this->x;
this->x=NULL;
}
if(this->y!=NULL){
delete this->y;
this->y=NULL;
}
//this->x=p.x; //编译器提供的代码是浅拷贝
this->x=new int(*p.x); //提供深拷贝 解决浅拷贝的问题
this->y=new int(*p.y);
return *this;
}
~point(){
if(this->x!=NULL){
delete this->x;
this->x=NULL;
}
if(this->y!=NULL){
delete this->y;
this->y=NULL;
}
}
};
int main(){
point p1(1,1);
point p2(2,2);
p1=p2;
cout<<*p1.x<<" "<<*p1.y<<endl;
return 0;
}
4.5.5 关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对象进行对比操作
示例:
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class point{
public:
int x,y;
point(int a,int b):x(a),y(b){}
bool operator==(const point &p){
if(this->x==p.x&&this->y==p.y) return 1;
else return 0;
}
};
int main(){
point p1(1,1);
point p2(2,2);
if(p1==p2) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
return 0;
}
4.5.6 函数调用运算符重载
特点
-
函数调用运算符 () 也可以重载
-
由于重载后使用的方式非常像函数的调用,因此称为仿函数
-
仿函数没有固定写法,非常灵活
示例:
#include <stdio.h>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
class print{
public:
void operator()(auto s){ //重载的()操作符 也称为仿函数
cout<<s<<endl;
}
};
class add{
public:
int operator()(int a,int b){
return a+b;
}
};
void test01(){
print p;
p("lys is dog");
}
void test02(){
add a;
cout<<a(1,2)<<endl;
}
int main(){
test01();
test02();
return 0;
}