一、什么是运算符重载
重载的运算符是具有特殊名字的函数:它们的名字由关键字operator和其要定义的运算符共同组成。例如:operator+()。和其他函数一样,重载的运算符也包含返回类型、参数列表、函数体
函数类型 operator运算符符号(形参列表)
{
对运算符的重载处理
}
二、为什么要运算符重载
1.运算符重载的作用
它允许你为类的用户提供一种直觉的接口,允许C/C++的运算符在用户定义类型(类)上拥有一个用户定义的意义
2.运算符重载有什么好处
通过重载类上标准运算符,你可以发掘类的用户的直觉,使用户程序所用的语言面向问题而不是机器,使得减少错误率
三、哪些运算符能被重载,哪些不能被重载
1.可被重载
C++本身内部运算符大部分可被重载
2.不可被重载
“ .”:类属关系运算符
”.*”:成员指针运算符
”::”:作用域运算符
“?:”:三目运算符
“sizeof”:测占字节运算符(也是关键字但主要这个不是函数)
3.通常情况下不应该被重载
逗号,取地址&,逻辑与和逻辑或运算符,因为C++已经定义了这些运算符特殊的含义,这一点 与大多数不同
4.浅析运算符有两个操作符在作为成员函数时参数只有一个,而作为非成员函数却回归正常有两个
1.例如”+“号运算符,重载时实际上有两个参数,但由于重载函数是类中的成员函数,所以有一个参数是隐含着的,运算符函数是用this指针隐含访问数据成员
C1+C2可以看出C1.operator+(C2);,即看成在C1中用C1的数据成员和引用C2对象的数据成员相加
2.而作为友元就可以堂堂正正有两个参数了
四、运算符重载如何实现
1.当运算符函数作为成员函数(几个常见实例)
(一).“+”,“-”,“*”,“/”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
class A{
public:
A();
A(double _x);
A operator+(A &a);
A operator-(A &b);
A operator*(A &c);
A operator/(A &d);
void show()
{
cout<<(double)x<<endl;
}
private:
double x;
};
A::A(double _x):x(_x)
{
}
A A::operator+(A &a)
{
A obj1(1);
obj1.x=x+a.x;
return A(obj1.x);
}
A A::operator-(A &a)
{
A obj1(1);
obj1.x=x-a.x;
return obj1.x;
}
A A::operator*(A &a)
{
A obj1(1);
obj1.x=x*a.x;
return obj1.x;
}
A A::operator/(A &a)
{
A obj1(1);
obj1.x=x/a.x;
return obj1.x;
}
int main()
{
A obj2(1.1);
A obj3(2.2);
A obj4(0.0);
obj4=obj2+obj3;
obj4.show();
obj4=obj3-obj2;
obj4.show();
obj4=obj2*obj3;
obj4.show();
obj4=obj3/obj2;
obj4.show();
return 0;
}
(二).“=”,“==”,“+=”,“-=”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
class A{
public:
A();
A(int _x);
A &operator=(A &a);
bool operator==(A &b);
A &operator+=(A &c);
A &operator-=(A &d);
void show()
{
cout<<x<<endl;
}
private:
int x;
};
A::A()
{
x=0;
}
A::A(int _x):x(_x)
{
}
A &A::operator=(A &a)
{
x=a.x;
// return x;
}
bool A::operator==(A &b)
{
if(x==b.x)
{
return 1;
}
else
{
return 0;
}
}
A &A::operator+=(A &c)
{
x=x+c.x;
//return A(x);
}
A &A::operator-=(A &d)
{
x=x-d.x;
//return A(x);
}
int main()
{
A obj2(1);
A obj3(2);
A obj4;
obj3+=obj2;
obj3.show();
obj3-=obj2;
obj3.show();
if(obj3==obj2)
{
obj3.show();
}
else
{
obj3=obj2;
obj3.show();
}
return 0;
}
(三).”++“,”- -“(a++有参,++a无参)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
class A{
public:
A();
A(int _x,int _y);
A &operator++();
A &operator++(int);
A &operator--();
A &operator--(int);
friend ostream &operator<<(ostream &output,A &m);
private:
int x;
int y;
};
A::A()
{
x=0;
y=0;
}
A::A(int _x,int _y):x(_x),y(_y)
{
}
A &A::operator++(int)//返回的是自增之前的值
{
A obj1(*this);
++(*this);
return obj1;
}
A &A::operator++()//返回自增之后的值
{
x++;
y++;
return *this;
}
A &A::operator--(int)//返回的是自减之前的值
{
A obj1(*this);
--(*this);
return obj1;
}
A &A::operator--()//返回自减自之后的值
{
x--;
y--;
return *this;
}
ostream &operator<<(ostream &output,A &m)
{
output<<m.x<<"--"<<m.y<<endl;
return output;
}
int main()
{
A obj2(1,1);
cout<<obj2++;
A obj3(1,1);
cout<<++obj3;
A obj4(1,1);
cout<<obj4--;
A obj5(1,1);
cout<<--obj5;
return 0;
}
三、当运算符函数作为非成员函数(友元)
(一).友元“+”
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
class A{
public:
A();
A(int _x);
friend A operator+(A &a,A &b);
void show()
{
cout<<x<<endl;
}
private:
int x;
};
A::A()
{
x=0;
}
A::A(int _x):x(_x)
{
}
A operator+(A &a,A &b)
{
A obj;
obj.x=a.x+b.x;
return obj.x;
}
int main()
{
A obj2(1);
A obj3(2);
A obj4;
obj4=obj3+obj2;
obj4.show();
return 0;
}
(二).“<<”、“>>”(输入输出运算符必须是非成员函数)
1.cout << XXX 这种情况是cout在调用operator<<而不是XXX在调用operator<< .如果你要把operator<<设为成员函数就只能用 XXX << cout 这种形式
2.假设输入输出运算符是某个类的成员,则它们也必须是istream或ostream的成员。然而,这两个类属于标准库,并且我们无法给标准库中的类添加任何成员
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <cmath>
#include <iostream>
using namespace std;
class A{
public:
A();
A(int _x);
friend ostream &operator<<(ostream &output,A &a);
friend istream &operator>>(istream &intput,A &b);
private:
int x;
};
A::A()
{
x=0;
}
A::A(int _x):x(_x)
{
}
ostream &operator<<(ostream &output,A &a)
{
output<<a.x;
return output;
}
istream &operator>>(istream &input,A &b)
{
input>>b.x;
return input;
}
int main()
{
A obj1;
cin>>obj1;
cout<<obj1;
return 0;
}