C++已经为基本类型和标注库中的数据类型提供了运算符操作,我们自定义数据类型的话有时就需要重载运算符实现自定义函数来实现类似功能了,此时可以把operator ==、operator=、operator*等操作符整体看作一个函数名。
一、单目运算符++/--(以++为例)
1、重载为类的成员函数
假设obj表示对象,func为成员函数,那么func的前置重载形式 func obj 相当于 obj.operator func(),无形参。前置++运算符表示先自增1然后返回对象本身,那么针对前置++就是++ obj表示obj.operator++()。
假设obj表示对象,func为成员函数,那么func的后置重载形式 obj func 相当于 obj.func(0),为了和前置运算符区分,有一个int型参数。后置++运算符表示先拷贝一份对象数据然后原对象自增1最后返回之前拷贝的对象数据,那么针对后置++就是 obj++ 表示obj.operator++(0)。
#include<stdio.h>
class Rational{
public:
Rational(int numerator,int denominator):mNumerator(numerator),mDenominator(denominator){}
Rational& operator++(){
printf("operator++(),front ++\n");
mNumerator++,mDenominator++;
return *this;
}
Rational operator++(int){//后置单目运算符有一个int形参
printf("operator++(),back ++\n");
Rational old=*this;
mNumerator++,mDenominator++;
return old;
}
void showData(){
printf("showData,mNumerator=%d,mDenominator=%d\n",mNumerator,mDenominator);
}
private:
int mNumerator,mDenominator;
};
int main(){
Rational a(3,4),b(3,4);
(a++).showData();
(++b).showData();
}
运行代码打印log如下:
operator++(),back ++
showData,mNumerator=3,mDenominator=4
operator++(),front ++
showData,mNumerator=4,mDenominator=5
2、重载为类的非成员函数
假设obj表示对象,func为成员函数,那么func的前置重载形式 func obj 相当于 operator func(obj)无形参。前置++运算符表示先自增1然后返回对象本身,那么针对前置++就是++ obj表示operator ++(obj)。
假设obj表示对象,func为成员函数,那么func的后置重载形式 obj func 相当于 operator func(obj,0)无形参。针对后置++就是++ obj表示operator ++(obj,0)。
注意:如果运算符的重载函数需要操作类的私有成员,需要将此函数声明为该类的友元。
#include<stdio.h>
class Rational{
public:
Rational(int numerator,int denominator):mNumerator(numerator),mDenominator(denominator){}
void showData(){
printf("showData,mNumerator=%d,mDenominator=%d\n",mNumerator,mDenominator);
}
friend Rational& operator++(Rational& rational); //声明友元函数
friend Rational operator++(Rational& rational,int); //声明友元函数
private:
int mNumerator,mDenominator;
};
Rational& operator++(Rational& rational){
printf("operator++(),front ++\n");
rational.mNumerator++,rational.mDenominator++;
return rational;
}
Rational operator++(Rational& rational,int){
printf("operator++(),back ++\n");
Rational old=rational;
rational.mNumerator++,rational.mDenominator++;
return old;
}
int main(){
Rational a(3,4),b(3,4);
(a++).showData();
(++b).showData();
}
运行打印log如下:
operator++(),back ++
showData,mNumerator=3,mDenominator=4
operator++(),front ++
showData,mNumerator=4,mDenominator=5
二、双目运算符
以+运算符重载为类的非成员函数举例
表达式obj1 func obj2 等同于 operator func(obj1,obj2),如果运算符的重载函数需要操作类的私有成员,需要将此函数声明为该类的友元。
#include<stdio.h>
class Rational{
public:
Rational(int numerator,int denominator):mNumerator(numerator),mDenominator(denominator){}
void showData(){
printf("showData,mNumerator=%d,mDenominator=%d\n",mNumerator,mDenominator);
}
friend Rational operator+(Rational rational1,Rational rational2);//声明友元函数
private:
int mNumerator,mDenominator;
};
Rational operator+(Rational rational1,Rational rational2){
printf("operator+\n");
return Rational(rational1.mNumerator+rational2.mNumerator,rational1.mDenominator+rational2.mDenominator);
}
int main(){
Rational a(3,4),b(3,4);
(a+b).showData();
}
运行打印log如下:
operator+
showData,mNumerator=6,mDenominator=8