可以知道,C++提供的operater重载运算符可以重载任何符号,这里讲解重载 () 和 [] 符号
1. 重载 [ ]
”[]”在c/c++一般是实现取数组元素的值操作,”[]”内的数值为数组的下标,数组的下标为整数,如ar[0]、ar[7]。现在要实现的功能是重载”[]”使其支持下标是字符串类型的,如ar[“1st”],怎么做?
重载操作符的原则是不能改变操作符的原有语义和操作数的个数,”[]”用于取元素的值,且只有一个操作数,为括号内的值,这个是不可被改变的,但是括号内的值是针对该数组而操作的,所以”[]”操作符肯定有一个数组对象,这也就决定了对”[]”的重载实现的函数只能是类的成员函数,因为类的成员函数具有this指针,它可以指向对象本身(对象可以内含一个数组嘛)。
class cls { private: int ar[6]; public: cls(); int& operator[] (int i); //重载"[]"操作符 }; cls::cls() { int i; for (i = 0; i < 6; i++) { ar[i] = i + 1; } } int& cls::operator[] (int i) //返回引用,这样才可以对返回值赋值 { return ar[i]; } int main(void) { cls c; printf("c[1] = %d\n", c[1]); c[4] = 16; printf("c[4] = %d\n", c[4]); return 0; }
从main()函数看,c是一个对象,却可以对对象利用”[]”进行下标操作,其实这也是可以对c++标准库中string类的对象进行”[]”操作的原因了。
class cls { //... public: int& operator[] (int i); //重载"[]"操作符,"[]"内的操作数的操作数是int类型 int& operator[] (const char* str); //重载"[]"操作符,"[]"内的操作数是字符串类型 }; int& cls::operator[] (const char* str) { //1st 2nd 3rd 4th 5th if (!strcmp("1st", str)) return ar[0]; if (!strcmp("2nd", str)) return ar[1]; if (!strcmp("3rd", str)) return ar[2]; if (!strcmp("4th", str)) return ar[3]; if (!strcmp("5th", str)) return ar[4]; if (!strcmp("6th", str)) return ar[5]; } int main(void) { cls c; printf("c[\"5th\"] = %d\n", c["5th"]); c["2nd"] = 66; printf("c[\"2nd\"] = %d\n", c["2nd"]); return 0; }
2. 重载()
在c/c++中。”()”操作符表示的是一个函数调用符号,同样,它只能够通过类的成员函数来重载:
class cls { public: void operator() () //重载"()"操作符,"()"内无操作数 { printf("HelloWorld!\n"); } void operator() (const char* str) //重载"()","()"内的操作数是字符串 { printf("%s", str); } }; int main(void) { cls cc; cc(); cc("Hello Linux\n"); return 0; }
再来看看在结构体中重载小括号的操作,例子是优先队列自定义优先级:
struct cmp1 { bool operator ()(int x, int y) { return x > y;//小的优先级高,由于使用的是!cmp1,所以就变成小的排最前 } }; priority_queue<int, vector<int>, cmp1> q2;
我们可以知道priority_queue的构造有两个,上面展示的是第二个,在结构体中使用重载小括号,即重载cmp1()的操作。等价于:
struct node { int x, y; friend bool operator < (node a, node b) { return a.x > b.x;//结构体中,x小的优先级高 } }; priority_queue<node> q4;