c++ operator的学习

来源:互联网 发布:淘宝原道电商讲师东风 编辑:程序博客网 时间:2024/06/05 19:23
<span style="font-family: Arial, Helvetica, sans-serif;">priority_queue 对于基本类型的使用方法相对简单。他的模板声明带有三个参数, Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。Container 必须是用数组实现的容器,比如 vector, deque 但不能用 list.STL里面容器默认用的是 vector. 比较方式默认用 operator< , 所以如果你把后面俩个参数 缺省的话,优先队列就是大顶堆,队头元素最大。</span>
实例
#include <queue>using namespace std;int main(){    priority_queue<int,vector<int>,less<int> >q1;//使用priority_queue<int> q1;一样,都是大根堆,没错,就是大根堆    for(int i=0;i<10;i++) q1.push(i);    while(!q1.empty()){        cout<<q1.top()<< endl;        q1.pop();    }    return 0;}
如果要用到小顶堆,则一般要把模板的三个参数都带进去。
STL里面定义了一个仿函数 greater<>,对于基本类型可以用这个仿函数声明小顶堆
例子: 变less<int> 为  greater<int>

#include <iostream>#include <queue>using namespace std;int main(){    priority_queue<int,vector<int>,greater<int> >q;    for(int i=0;i<10;i++) q.push(i);    while(!q.empty()){        cout<<q.top()<< endl;        q.pop();    }    return 0;}

自定义类型,要重载运算符,由于priority_queue默认的是operator<,so 重载这个(记住!)

两种是等价的

1:

#include <iostream>#include <queue>using namespace std;struct Node{int x, y;bool operator<( const Node &b)const//为什么这么多const(只读)和&(引用)<span style="font-family: Arial, Helvetica, sans-serif;">   该问题在下文,会提到</span>
{    if(x==b.x) return y>b.y;    return x>b.x;}//定义为成员函数,只有当运算符左边为该结构体变量时,才起作用}node;  int main(){    priority_queue<Node>q;    for(int i=0;i<10;i++){    node.x=i;    node.y=10-i/2;    q.push(node);    }    while(!q.empty()){        cout<<q.top().x <<' '<<q.top().y<<endl;        q.pop();    }    return 0;}

2:

#include <iostream>#include <queue>using namespace std;struct Node{int x, y;}node; bool operator<( Node a, Node b){    if(a.x==b.x) return a.y>b.y;    return a.x>b.x;}//在结构体外面定义,为全局名字空间的成员,定义在外面,运算符左边的可以不是结构体变量,也就是说,此处前一个的Node 允许换为int
//同时,放在结构体外面,就不用放那些麻烦的const & int main(){    priority_queue<Node>q;    for(int i=0;i<10;i++){    node.x=i;    node.y=10-i/2;    q.push(node);    }    while(!q.empty()){        cout<<q.top().x <<' '<<q.top().y<<endl;        q.pop();    }    return 0;}

C:如何决定把一个操作符重载为类成员函数还是全局名字空间的成员呢?
如果一个重载操作符是类成员,那么只有当与他一起使用的左操作数是该类的对象时,该操作符才会被调用。如果该操作符的左操作数必须是其他的类型,则操作符必须被重载为全局名字空间的成员。
②C++要求赋值=,下标[],调用(), 和成员指向-> 操作符必须被定义为类成员操作符。任何把这些操作符定义为名字空间成员的定义都会被标记为编译时刻错误。
③如果有一个操作数是类类型如string类的情形那么对于对称操作符比如等于操作符最好定义为全局名字空间成员。



注意:

以前一直有一个不明白的问题,对于sort来说,cmp函数只要是<,那么就是小于,然后升序;>就是从大到小

但是看很多其他的定义来说,就不是这个样子,和想象的相反

struct Node{<span style="white-space:pre"></span>int x, y;<span style="white-space:pre"></span>bool operator<( const Node &b)const<span style="white-space:pre"></span>{ <span style="white-space:pre"></span>if(x==b.x) return y>b.y;<span style="white-space:pre"></span>return x>b.x;<span style="white-space:pre"></span>}//例如这里,这是上文优先队列的重载,意思是说按x为第一关键字,y为第二关键字,的小根堆,但是注意上面是operator <
//下面就成了x>b.x,不对啊?事实上,优先队列内部就是一个堆,里面的运算符均为<,即默认的运算符,但是我们把他赋予了>的意义,为什么要赋予>的意思n呢?因为,在priority_pueue内部,默认是大根堆,也就是说,如果根节点<span style="color:#ff0000;">小于</span>一个孩子的话,那么交换(<就是用在这里)我们把他要改为小根堆,那么就是如果根节点大,才交换,<的符号没变,只是代表了>而以。x呢就是运算符左边的,b.x自然就是右边的。
}node;
差不多明白了

不过那些cosnt 和& 是干什么的

认识一些概念

1. 比如你定义一个函数void add(int a, int b),这里的a和b就是形参
2. 当你进行函数调用的时候,add(1, 2),这里的1和2就是实参

bool operator<( const Node &b)const{    if(x==b.x) return y>b.y;    return x>b.x;}

刚刚的问题,如果第一个const和&删了,没事;&删了没事;第二个const删了就不行;

还有如果光是第一个const删了(&不动),也会报错

因为:如果使用引用类型的实参的唯一目的是为了避免大量的复制实参而不对实参做修改,最好使用的形参类型为const 类型名&。这也就是为什么上面用const node &b,所以,一定要加上,第二个const就直接背过即可。

详见:http://blog.csdn.net/guiyinzhou/article/details/6298030  C++『const 引用 传参』『类成员函数』



代码写的很屎,主要是练一下类的重载运算符,明白了const到底是干吗用的:

[cpp] view plain copy
 print?
  1. bool operator <(const point b)const{  
  2.     return a.x<b.x;  
  3. }  

第一个const 保证b不被改变,第二个const 保证原变量不被改变。

写这些大致想保证该不被改变的就不被改变吧(否则出现编译错误)。。!!!!!!!!!!!



1 0