定义一个复数类,实现两个复数相加功能
#include<iostream>
using namespace std;
class complex{
private:
int real;
int image;
public:
complex(){}
complex(int real,int image){
this->real=real;
this->image=image;
}
void setReal(int value){
real=value;
}
void setImage(int value){
image=value;
}
int getReal(){
return real;
}
int getImage(){
return image;
}
void display(){
cout<<real<<'+'<<image<<'i'<<endl;
}
complex add(const complex &a)const{
complex b;
b.setReal(real+a.getReal());
b.setImage(image+a.getImage());
return b;
}
};
int main(){
complex a(1,2);
complex b(3,4);
complex c;
c=a.add(b);
c.display();
return 0;
}
}
结果:

复数类通过成员函数add()实现了两个复数类的相加功能。
是否有办法使用易于理解的a+b表达式的形式实现两个复数类相加呢?当然有。c++提供运算符重载功能。可以实现对自定义类实现+、-、*、%等各种运算符的运算。只需要在成员函数中定义operator()函数就可以实现对运算符的重载
例子:
#include<iostream>
using namespace std;
class complex{
private:
int real;
int image;
public:
complex(){}
complex(int real,int image){
this->real=real;
this->image=image;
}
void setReal(int value){
real=value;
}
void setImage(int value){
image=value;
}
int getReal()const{
return real;
}
int getImage()const{
return image;
}
void display(){
cout<<real<<'+'<<image<<'i'<<endl;
}
//运算符重载函数operator+
complex operator+(const complex &a)const{
complex b;
b.setReal(real+a.getReal());
b.setImage(image+a.getImage());
return b;
}
};
int main(){
complex a(1,2);
complex b(3,4);
complex c;
c=a+b;
c.display();
return 0;
}
结果:

通过定义operator+()函数实现了两个类c=a+b表达式形式的加法运算。此时的c=a+b相当于c=a.operator+(b)。同样的,也可以使用以上方法重载-、*、/等运算符。即在类中定义operator-()、operator*()、operator/()等成员函数。
运算符重载,至少有一个操作数是用户自定义的类型,这将防止用户为标准类型重载运算符,比如,你不能为两个标准类型的double值去重载运算符+。
当两个操作数有一个是自定义类,而另一个是标准类型时,如要实现complex类与int值相加,实现复数实部的增加,可以在complex类中继续定义一个成员函数
可以使用
来实现,相当于调用a.operator+(2);而如果是
呢?显然不行的,因为int型没有operator+()这个成员函数
解决办法可以是让所有人使用a+2这个形式,而不是2+a,这显然是我们不希望使用的方法
还有一种办法就是使用非成员函数形式实现运算符重载,由于运算符重载函数需要访问类的内部空间,需要将此函数定义为该类的友元函数。友元函数不是类的成员函数,但是与类成员函数具有相同的访问权限。
实现:
#include<iostream>
using namespace std;
class complex{
private:
int real;
int image;
public:
complex(){}
complex(int real,int image){
this->real=real;
this->image=image;
}
void setReal(int value){
real=value;
}
void setImage(int value){
image=value;
}
int getReal()const{
return real;
}
int getImage()const{
return image;
}
void display(){
cout<<real<<'+'<<image<<'i'<<endl;
}
complex operator+(const complex &a)const{
complex b;
b.setReal(real+a.getReal());
b.setImage(image+a.getImage());
return b;
}
complex operator+(const int &a)const{
complex b;
b.setReal(real+a);
b.setImage(image);
return b;
}
//定义非成员函数operator+
friend complex operator+(int a,const complex &b);
};
complex operator+(int a,const complex &b){
complex c;
c.setReal(a+b.getReal());
c.setImage(b.getImage());
return c;
}
int main(){
complex a(1,2);
complex c;
complex d;
c=a+2;
c.display();
d=4+a;
d.display();
return 0;
}
结果:

可以看到,将operator+(int a,const complex &b)定义为非成员函数,这样对于类似c=4+a这样的表达式,会转换为c=operator+(4,a),从而调用刚才定义的非成员友元函数。
虽然通过非成员友元函数的方法也可以进行运算符重载,但是下列运算符只能通过定义为成员函数的方法进行重载
|运算符|说明 |
|--|--|
| = |赋值运算符 |
|() |函数调用运算符 |
| []| 下标运算符|
| ->| 通过指针访问类成员的运算符|
也有一些运算符,不能进行重载
|运算符|说明 |
|--|--|
|sizeof| sizeof运算符|
| .| 成员运算符|
| .*| 成员指针运算符|
| ::| 作用域解析运算符|
| ?:| 条件运算符|
| typeid| 一个RTTI运算符|
| const_cast| 强制类型转换运算符|
| dynamic_cast| 强制类型转换运算符 |
| reinterpret_cast| 强制类型转换运算符 |
|static_cast|强制类型转换运算符|
Tips:
对于单目运算符++的重载,如何区分重载的左侧++i还是右侧i++
实际上默认重载运算符在左侧的情况,如果对运算符在右边的情况重载,需要在重载函数参数列表中加入一个int
例子:
#include<iostream>
using namespace std;
class complex{
private:
int real;
int image;
public:
complex(){}
complex(int real,int image){
this->real=real;
this->image=image;
}
void setReal(int value){
real=value;
}
void setImage(int value){
image=value;
}
int getReal()const{
return real;
}
int getImage()const{
return image;
}
void display(){
cout<<real<<'+'<<image<<'i'<<endl;
}
//重载++i
complex operator++(){
real+=1;
image+=1;
}
//重载i++
complex operator++(int){
real+=1;
image+=1;
}
};
int main(){
complex a(1,2);
complex b(5,7);
++a;
b++;
a.display();//2+3i
b.display();//6+8i
return 0;
}