结构体的运算符重载

C++中,结构体是无法进行==,>,<,>=,<=,!=操作的,如要使用这些操作符对结构体进行操作,则可以在结构体内部对这些运算符进行重载,将结构体的比较转化为结构体内部的数字或者字符的比较。

实际编程中,大部分时候操作对象是结构体数组,尤其是在使用STL容器的时候,如果我们可以往语句中传入结构体,一些事情将会变得很简单。因此掌握结构体运算符的重载是非常必要的。
 

方式一:结构体内部的重载

重载运算符的格式如下:
bool operator 运算符 (const 结构体名称 b) const
{
    return(什么时候这个运算符对结构体成立);
}

 

 

 

  priority_queue<tmp>q;//优先队列 

方式二:结构体外的重载

 

 

 

 

priority_queue<tmp,vector<tmp>,cmp>q;;//优先队列 

 

 
 

来源1:https://blog.csdn.net/sunny1996/article/details/51242184

来源2:简书

 来源3:https://www.cnblogs.com/MekakuCityActor/p/8455379.html

关于结构体运算符重载解释的比较清楚的文章:http://www.cppblog.com/sixleaves/archive/2014/08/29/208178.aspx

 

运算符重载-友原函数(结构体、类和运算符重载

 

第一:运算符重载的基本应用。第二:运算符重载于友原函数的关系。第三:结构体于类关于运算符重载的区别。首先我需要普及下基本的知识:
预备知识operator(操作符)、operand(操作数)、表达式
表达式是由操作符和操作数构成的,而且一般每个表达式都有副作用,并且都有结果(关注结果和副作用)。什么意思?
关于副作用的理解:其实就是在达到结果的这个过程中所做的一些事情,而这些事情产生了一些影响,但是不影响结果。
好像有点绕、看看例子在理解吧。
看例子:
int a = 1,b=2,c; c = a + b;
在这段代码里面,c = a + b;就是表达式、其中 = 、 + 又称为操作符、c、a、b又称为操作数。其结果就是计算出了a+b的值,副作用没有。
又比如:
cout << "Helloe" << endl;其中 <<是操作符、cout、"helloe"、endl是操作数。<<的结果是返回了ostream的引用,而副作用就是将"Helloe"输出到屏幕。

第一:运算符重载的基本应用。
看如下代码:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 class Point {
 6 private:
 7     double x,y;
 8 public:
 9     Point(double x = 0, double y = 0):x(x),y(y) {
10         
11     }
12     Point operator+(const Point &p) const{//这种是最基本的方式、其本质是做操作数调用operator+函数 
13         Point temp;
14         temp.x = this->x + p.x; 
15         temp.y = this->y + p.y;
16         return temp;
17     }
18     /*
19     ostream& operator<<(ostream& out) {
20         out << x << " " << y;
21         return out;
22     }
23     */
24     friend ostream& operator<<(ostream& out, Point & p);   
25 };
26 ///*
27 ostream& operator<<(ostream& out, Point & p) {
28     out << p.x <<" "<< p.y;
29     return out;
30 }
31 //*/
32 
33 int main() {
34     
35     Point a(1,5);
36     Point b(5,7);
37     Point c;
38     c = a + b;
39     //c << cout << endl;
40     cout << c << endl; 
41     return 0;
42 }

如上代码:
注释掉的先不用看,12--17行就是最基本的运算符重载、其调用在38行,本质是:c = a.operator+(b);也就是调用做操作数的方法那么还要友元函数干什么呢?考虑下输出,如果你想让cout对象能自动输出Point的对象如何半到。你很聪明一定想到重载<<运算符、yes!right!于是把operator<<作为成员函数,你只能写成上面注释掉的哪样,那么调用时,麻烦就来了、编程39行的样子。尼玛丫、真实变态、我是想让它是cout << c << endl。搞得四不像了。是的就是因为这样子不好用,所以我们要结合友元函数的技术和运算重载技术来实现40行的调用。好了重点来了!谨记之!
tips:对于非成员函数的运算符重载,第一个参数就是左操作数,第二个操作数就是右操作数。
第二:运算符重载和友原函数的关系
所以上面的友元函数的参数顺序是cout对象的引用是第一个参数、Point对象引用为第二个参数。
我们还要解决第二个问题,如何让这个函数访问Point对象的私有部分,只要在Point类中声明,hello我是你的朋友啦、他的东西就是你的啦、你要怎么用怎么用,这才是朋友么!不、是基友!我认为应该叫做基友函数,哈哈。声明格式就是加上friend和函数的声明即可。
tips:成员函数和非成员函数的运算符重载的区别就是,参数个数不一样。成员函数中的左操作数不用体现出来(用this即可)、而非成员函数的左右操作数都要体现在运算符函数参数里面。
第三:结构体和类关于运算符重载的区别
关于区别,其实只有一个,因为结构体默认的权限是public、即其成员对外界都是可见的,所以其不需要友元函数来支持,但是其还是需要用非成员函数来重载<<比较方便、而不是用成员函数来重载<<.原因上面已经说过了。注意这个原因不是友元这项技术体现出来的,而是成员函数和非成员函数体现出来的,友元技术知识用来支撑其在类中的应用。、
tips:对于结构体,非成员函数的运算符重载方法,不需要声明为友元函数。
如下代码:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 struct Point{
 6     double x,y;
 7     Point(double x = 0, double y = 0):x(x),y(y) {
 8         
 9     }
10     Point operator+(const Point &p) const{//这种是最基本的方式、其本质是做操作数调用operator+函数 
11         Point temp;
12         temp.x = this->x + p.x; 
13         temp.y = this->y + p.y;
14         return temp;
15     }
16 };
17 
18 ostream& operator<<(ostream& out, Point & p) { 
19     out << p.x <<" "<< p.y;
20     return out;
21 }
22 
23 
24 int main() {
25     
26     Point a(1,5);
27     Point b(5,7);
28     Point c;
29     c = a + b;
30     cout << c << endl; 
31     return 0;
32 }