重载运算符介绍:
重载运算符是通过对运算符的重新定义,使得其支持特定数据类型的运算操作。重载运算符是重载函数的特殊情况。
C++ 自带的运算符,最初只定义了一些基本类型的运算规则。当我们要在用户自定义的数据类型上使用这些运算符时,就需要定义运算符在这些特定类型上的运算方式。
重载运算符,可以部分程度上代替函数,简化代码。
来个栗子:我们要设计一个名为“person”的类,现在要判断person类的两个对象p1和p2是否一样大,我们设计的比较规则是按照其年龄来比较,那么,在设计person类的时候,就可以通过对操作符“==”进行重载,来使用操作符“==”对对象p1和p2进行比较了(就是把“==”重载成“>”或“<”)
限制:
- 只能对现有的运算符进行重载,不能自行定义新的运算符。
- 以下运算符不能被重载:
::
(作用域解析),.
(成员访问),.*
(通过成员指针的成员访问),?:
(三目运算符)。 - 重载后的运算符,其运算优先级,运算操作数,结合方向不得改变。
- 对
&&
(逻辑与)和||
(逻辑或)的重载失去短路求值。
实现:
重载运算符分为两种情况,重载为成员函数或非成员函数。
重载运算符的模板大致可分为下面几部分:
/*类定义内重载*/ 返回类型 operator符号(参数){
......
}
/*类定义内声声明,再外部定义*/ 返回类型 类名称::operator符号(参数){
......
}
再举个例子(干讲太累):
class Vector{
public:
int x,y;
Vector(): x(0),y(0) {}
Vector(int _x,int _y) : x(_x),y(_y){}
int operator*(const Vector& other){
return x*other.x+y*other.y;
}
int operator+(const Vector& other){
return Vector(x+other.x,y+other.y);
}
int operator-(const Vector& other){
return Vector(x-other.x,y-other.y);
}
};
// 关于4行表示为x,y赋值,具体实现参见后文。
当然你也可以写在外面:
class Vector{
public:
int x,y;
Vector(): x(0),y(0) {}
Vector(int _x,int _y) : x(_x),y(_y){}
Vector operator*(const Vector&);
Vector operator+(const Vector&);
Vector operator-(const Vector&);
};
Vector Vector::operator*(const Vector& other){
return x*other.x+y*other.y;
}
Vector Vector::operator+(const Vector& other){
return Vector(x+other.x,y+other.y);
}
Vector Vector::operator-(const Vector& other){
return Vector(x-other.x,y-other.y);
}
该例定义了一个向量类,并重载了 * + -
运算符,并分别代表向量内积,向量加,向量减。
函数调用运算符:
函数调用运算符 ()
只能重载为成员函数。通过对一个类重载 ()
运算符,可以使该类的对象能像函数一样调用。
重载 ()
运算符的一个常见应用是,将重载了 ()
运算符的结构体作为自定义比较函数传入优先队列等 STL 容器中。
下面就是一个例子:给出 n 个学生的姓名和分数,按分数降序排序,分数相同者按姓名字典序升序排序,输出排名最靠前的人的姓名和分数。(未编译的代码可能有些许错误!)
#include<bits/stdc++.h>
using namespace std;
struct student{
string name;
int score;
};
struct cmp{
bool operator()(const student& a,const student& b) const{
return a.score<b.score || (a.score==b.score && a.name>b.name);
}
};
priority_queue<student, vector<student>,cmp> pq;
int main(){
int n;
cin>>n;
for(int i=1;i<=n;i++){
//放心不与结构体重名,因为不会互相影响
string name;
int score;
cin>>name>>score;
qp.push({name,score});
}
student rk1=pq.top();
cout<<rk1.name<<" "<<rk1.score<<"\n";
return 0;
}
比较运算符:
在 std::sort
和一些 STL 容器中,需要用到 <
运算符。在使用自定义类型时,我们需要手动重载。
还是以讲函数调用运算符时举的例子说起,如果我们重载比较运算符,实现代码是这样的(主函数因为没有改动就略去了):
struct student{
string name;
int score;
bool operator<(const student& a) const{
return score<a.score || (score==a.score && name>a.name);
}
};
priortiy_queue<student> pq;
同理你也可以在外面重载:
struct student{
string name;
int score;
};
bool operator<(const student& a,const student& b){
return a.score<b.score || (a.score==b.score && a.name>b.name);
}
priority_queue<student> pq;
知道了小于好其它符号也很好实现了QAQ:
bool operator<(const T& a,const T& b){
return a>b;//把小于号重载成大于号
}
bool operator>(const T& a,const T& b){
return a<b;//把大于号重载成小于号
}
bool operator<=(const T& a,const T& b){
return !(a>b);//把小于等于号重载成小于等于号
}
bool operator>=(const T& a,const T& b){
return !(a<b);//把大于等于号重载成大于等于
}
bool operator==(const T& a,const T& b){
return !(a<b) && !(a>b);//把等于重载为等于
}
bool operator!=(const T& a,const T& b){
return !(a==b);//把非重载未非
}
总结:
感谢观看到这里,创作不易点给赞再走哦QAQ
用好重载运算符可以简化代码,所以一定要用清楚!
拜拜~~~