一、概念
C++中运算符重载是为了实现对象之间进行各种运算的特定语法,在某些特定的场合起到重要的作用,新建重载方法需用operator关键字进行修饰。
可以重载运算符包括+、-、*、\、赋值运算符=、左移运算符<<、递增运算符++、递减运算符- -、关系运算符、函数调用运算符()等。
运算符重载需要遵守以下规则:
1 重载时不能违法运算符原来的句法规则。
2 只能重载C++定义的运算符。
3 不能改变运算符原有的优先级。
4 运算符的结合性不能被改变。
5 不能进行重载的运算符:成员运算符(.),(::),条件运算符,sizeof、强制类型转换运算符。
6 运算符的目数(又称“元数”,即运算符所需要的操作数的数目)不能被改变。
7 当重载“()”、“[]、“->”、=时,运算符重载函数必须被声明为类成员。
二、程序示例
1. 加减乘除重载
#include<iostream>
using namespace std;
class MyFloat
{
//成员函数重载运算符
public:
//MyFloat operator+(MyFloat& myf)
//{
// MyFloat temp;
// temp.N1 = this->N1 + myf.N1;
// temp.N2 = this->N2 + myf.N2;
// return temp;
//}
MyFloat operator-(MyFloat& myf)
{
MyFloat temp;
temp.N1 = this->N1 - myf.N1;
temp.N2 = this->N2 - myf.N2;
return temp;
}
MyFloat operator*(MyFloat& myf)
{
MyFloat temp;
temp.N1 = this->N1 * myf.N1;
temp.N2 = this->N2 * myf.N2;
return temp;
}
MyFloat operator/(MyFloat& myf)
{
MyFloat temp;
temp.N1 = this->N1 / myf.N1;
temp.N2 = this->N2 / myf.N2;
return temp;
}
public:
float N1;
float N2;
};
//全局函数重载运算符
MyFloat operator+(MyFloat& Myf1, MyFloat& Myf2)
{
MyFloat temp;
temp.N1 = Myf1.N1 + Myf2.N1;
temp.N2 = Myf1.N2 + Myf2.N2;
return temp;
}
MyFloat operator+(MyFloat& Myf1, int N)
{
MyFloat temp;
temp.N1 = Myf1.N1 + N;
temp.N2 = Myf1.N2 + N;
return temp;
}
int main()
{
MyFloat myf1;
myf1.N1 = float(3.6);
myf1.N2 = float(3.4);
MyFloat myf2;
myf2.N1 = float(3.6);
myf2.N2 = float(3.4);
/*MyFloat myf3 = myf1.operator+(myf2);*///本质写法
/*MyFloat myf3 = operator+(myf1, myf2);*/
MyFloat myf3 = myf1 + myf2;//简化写法
MyFloat myf31 = myf1 + 1;
MyFloat myf4 = myf1 - myf2;
MyFloat myf5 = myf1 * myf2;
MyFloat myf6 = myf1 / myf2;
cout << myf3.N1 << " " << myf3.N2 << endl;
cout << myf31.N1 << " " << myf31.N2 << endl;
cout << myf4.N1 << " " << myf4.N2 << endl;
cout << myf5.N1 << " " << myf5.N2 << endl;
cout << myf6.N1 << " " << myf6.N2 << endl;
}
7.2 6.8
4.6 4.4
0 0
12.96 11.56
1 1
2. 赋值运算符重载
#include<iostream>
using namespace std;
class MyFloat
{
public:
MyFloat(float n)
{
N = new float(n);
}
//赋值运算符
MyFloat& operator=(MyFloat &myf)
{
//先判断是否有堆区的属性
if (N != NULL)
{
delete N;
N = NULL;
}
//深拷贝
N = new float(*myf.N);
return *this;
}
//如果不加赋值运算符重载,对象的赋值操作会引发内存重复释放的异常。
~MyFloat()
{
if (N != NULL)
{
delete N;
N = NULL;
}
}
float *N;
};
int main()
{
MyFloat myf1(1.1415);
MyFloat myf2(2.1415);
MyFloat myf3(3.1415);
myf3 = myf2 = myf1;
cout << *myf3.N << endl;;
cout << *myf2.N << endl;;
}
3. 递增递减运算符重载
#include<iostream>
using namespace std;
class MyFloat
{
friend ostream& operator<<(ostream& cout, MyFloat myf);
public:
MyFloat()
{
N = 3.1415;
}
//重载前置++运算符,返回类型为引用,是因为如果不加,返回值属于值类型,重载函数运行完后会销毁
//运行完后N的值始终只会加一次1,如果再调用重载,N的值不会一直加1
MyFloat& operator++()
{
//先进行++计算
N++;
return *this;
}
//重载后置++运算符,int代表占位参数,用于区分前置后置
MyFloat& operator++(int)
{
//先记录当时的结果
MyFloat temp = *this;
//后递增
N++;
return temp;
}
//重载前置--运算符
MyFloat& operator--()
{
//先进行--计算
N--;
return *this;
}
//重载后置--运算符,int代表占位参数,用于区分前置后置
MyFloat& operator--(int)
{
//先记录当时的结果
MyFloat temp = *this;
//后递减
N--;
return temp;
}
private:
float N;
};
ostream& operator<<(ostream & cout, MyFloat myf)
{
cout << myf.N;
return cout;
}
int main()
{
//后置重载
MyFloat myf;
cout << myf++ << " " << endl;
cout << myf << endl;
cout << myf-- << " " << endl;
cout << myf << endl;
MyFloat myf1;
cout << ++myf1 << " " << endl;
cout << ++(++myf1) << " " << endl;
//又调用一次++相当于先调用了一次拷贝构造函数,然后再调用重载,拷贝构造函数会重新创建一个拷贝的值的内存,再运行完后销毁。
//如果重载返回值类型不加&,会直接销毁++myf1的拷贝值,加&,会创建一个指针常量,一直指向内存中的N,返回值也会一直是类中的N,而不是拷贝的N的值。
cout << myf1 << endl;
cout << --myf1 << " " << endl;
cout << myf1 << endl;
}
3.1415
4.1415
4.1415
3.1415
4.1415
4.1415
3.1415
3.1415
4. 关系运算符重载
#include<iostream>
using namespace std;
class MyFloat
{
public:
MyFloat(float n)
{
N = n;
}
//等于运算符
bool operator==(MyFloat& myf)
{
if (this->N == myf.N)
{
return true;
}
else
{
return false;
}
}
//大于运算符
bool operator>(MyFloat& myf)
{
if (this->N > myf.N)
{
return true;
}
else
{
return false;
}
}
float N;
};
int main()
{
MyFloat myf1(1.1415);
MyFloat myf2(1.1415);
MyFloat myf3(3.1415);
if (myf1 == myf2)
{
cout << "myf1与myf2相等" << endl;
}
if (myf3 > myf2)
{
cout << "myf3大于myf2" << endl;
}
}
myf1与myf2相等
myf3大于myf2
5. 左移运算符重载
#include<iostream>
using namespace std;
class MyFloat
{
friend ostream& operator<<(ostream& cout, MyFloat myf);
public:
MyFloat()
{
N = 3.1415*N1;
}
private:
float N;
float N1 = float(2);
};
//重载左移运算符,只能利用全局函数重载。成员函数重载时会发生cout在右侧。
//ostream类只能用引用的方式声明对象。
ostream& operator<<(ostream & cout, MyFloat myf)
{
cout << myf.N;
return cout;
}
int main()
{
MyFloat myf;
cout << myf << endl;
}
6.283
6. 函数调用运算符重载
#include<iostream>
using namespace std;
class MyFloat
{
public:
MyFloat(float n)
{
N = n;
}
//函数调用运算符
float operator()(float n1,float n2)
{
return n1 + n2;
}
float N;
};
int main()
{
MyFloat myf(0);
float c = myf(float(1.1415), float(1.1415));//与函数调用相似,又称为仿函数
cout << c << endl;
cout << MyFloat(0)(float(1.1415), float(1.1415)) << endl;//匿名对象
}