第一先给出搬运资料:
https://baike.baidu.com/item/c%2B%2B%E8%BF%90%E7%AE%97%E7%AC%A6 百度百科所有运算符列表
https://blog.csdn.net/insistgogo/article/details/6626952 来自 C++_运算符重载 - 思考,思考,再思考- - CSDN博客
1.重载运算符
重载运算符是一种c++给类的功能一种扩展 使类能够使用运算符操作一样 实际上 当使用类似a++ 这种运算时自动调用了我们自己写好的重载函数:
#include <iostream>
using namespace std;
class A
{
public:
A(int x, int y) :x(x), y(y){}
void operator ++()
{
cout << "重载运算符++"<<endl;
this->x++;
this->y++;
}
void show()
{
cout << x <<" "<<y<<endl;
}
private:
int x;
int y;
};
void main()
{
A a(7, 8);
a.show();//显示结果为 7 8
++a;//调用自定义的重载函数++
a.show();//显示结果为 8 9
system("pause");
}
2.友元函数和成员函数
既然我们了解到我们可以使用函数重载,那么有那些函数可以重载呢?
友元重载运算符函数特性: 可以访问类的私有变量,不含有类的this指针
成员重载运算符函数特性:只可以访问“当前所属类”的私有变量,含有this指针
这里就用到了CSDN博客的例子:
class Point
{
private:
int x;
public:
Point(int x1)
{ x=x1;}
Point(Point& p)
{ x=p.x;}
const Point operator+(const Point& p);//使用成员函数重载加号运算符
friend const Point operator-(const Point& p1,const Point& p2);//使用友元函数重载减号运算符
};
const Point Point::operator+(const Point& p)
{
return Point(x+p.x);//这里的x隐含了this指针
}
Point const operator-(const Point& p1,const Point& p2)
{
return Point(p1.x-p2.x);
}
以及调用方法
Point a(1);
Point b(2);
a+b; //正确,调用成员函数
a-b; //正确,调用友元函数
a+1; //正确,先调用类型转换函数,把1变成对象,之后调用成员函数
a-1; //正确,先调用类型转换函数,把1变成对象,之后调用友元函数
1+a; //错误,调用成员函数时,第一个操作数必须是对象,因为第一个操作数还有调用成员函数的功能
1-a; //正确,先类型转换 后调用友元函数
所以通过例子总结如下:
如果是一元运算符 例如a++ 、!a 、~a、new a、等等 这些运算符的对象只有一个,即我们定义的对象A ,这些运算符建议使用成员函数。
如果是二元运算符 +- */一般要考虑 运算的对象是什么 如果类似a1+a2 种 在A本类之间运算可以采用成员函数 如果是有一个类B 想要运算a+b 如果a,b运算时都需要访问各自类的私有成员建议使用友元函数
另外有些运算符必须使用相应的函数
运算符 | 函 |
= ( ) [ ] -> | 必须是成员函数 |
cout<< cin>> | 必须是友元函数 |
3.参数
额外说明:cout << a 要实现这种运算符 需要使用到类似这种函数定义:
friend ostream & operator <<(ostream & out, A & a);
<< 对象左边是ostream对象 即标准输入流类 cout即对应out参数 而a为>>右边的对象,
我们可以看如下奇怪的定义和匹配的奇怪的调用格式:
调用函数参数返回值格式 | 调用格式 | 类型 | 返回值 | 函数名 | 参数 |
ostream & operator <<(A & b); | a<<b; | 成员 | ostream & | operator << | A & b (this指针) |
ostream & operator <<(ostream & out); | a<<cout; | 成员 | ostream & | operator << | ostream & (this指针) |
friend ostream & operator <<(A & a,ostream & out); | a<<cout; | friend | ostream & | operator << | A & a,ostream & out |
friend ostream & operator <<(ostream & out, A & a); | cout<<a; | friend | ostream & | operator << | ostream & out,A & a |
很明显,同样的函数重载:参数不同导致了调用格式不同,服务对象也不同 同样的参数置换了位置(例子3 和4 ) 调用也发生了变化。
返回值说明: 返回值代表这个运算的结果 如果说单独调用只需要函数内部运算,不需要结果可以返回void 。
4.总结:
1.运算符的第一操作对象决定是使用成员函数还是友元函数
2.重载的参数顺序和类型决定要使用什么样的对象和对象间重载
3.返回值代表这个运算符可以提供的运算结果