先说一下不能被重载的五个操作符:
- .:成员访问运算符
- .* ->* 成员指针访问运算符
- :::域运算符
- sizeof:长度运算符
- ?::条件运算符
- #: 预处理符号
ps:对成员指针访问运算符比较陌生,在这里记录一下:成员指针访问运算符,通常是指向一个类的成员。
下面例子说明了成员指针 .* 的用法,当使用对象或对象的引用来范围类的成员时,必须用.*:
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 class myclass { 6 public: 7 int 8 sum; 9 void myclass::sum_it(int x); 10 }; 11 12 void myclass::sum_it(int x) 13 { 14 15 int 16 i; 17 sum = 0; 18 for(i = x; i; i--) { 19 sum += i; 20 }} 21 22 int _tmain(int argc, _TCHAR* argv[]){ 23 24 int myclass::*dp; //指向 myclass 中整数类型成员变量的指针 25 void (myclass::*fp)(int x); //指向 myclass 中成员函数的指针 26 27 myclass c; 28 dp = &myclass::sum; //获得成员变量的地址 29 fp = &myclass::sum_it; //获得成员函数的地址 30 31 (c.*fp)(7); //计算 1 到 7 相加的和 32 33 cout << "summation of 7 is " << c.*dp; 34 return 0; 35 36 }
如果指向对象的指针来访问对象的成员,那么必须使用 ->* 运算符,上面的程序改写一下:
1 #include "stdafx.h" 2 #include <iostream> 3 using namespace std; 4 5 class myclass { 6 public: 7 int 8 sum; 9 void myclass::sum_it(int x); 10 }; 11 12 void myclass::sum_it(int x) 13 { 14 15 int 16 i; 17 sum = 0; 18 for(i = x; i; i--) { 19 sum += i; 20 }} 21 22 int _tmain(int argc, _TCHAR* argv[]){ 23 24 int myclass::*dp; //指向 myclass 中整数类型成员变量的指针 25 void (myclass::*fp)(int x); //指向 myclass 中成员函数的指针 26 27 myclass *a,c ; 28 dp = &myclass::sum; //获得成员变量的地址 29 fp = &myclass::sum_it; //获得成员函数的地址 30 a = &c //指针a指向c的对象 31 (c->*fp)(7); //这里使用指向对象的指针来访问对象的成员,必须用->* 32 33 cout << "summation of 7 is " << c.*dp; 34 return 0; 35 36 }
回到正题,继续说操作符的重载:
操作符的重载声明的格式为:<返回值> operator 操作符(<参数列表>);
其实操作符的重载也是重载的一种,和函数重载很类似,可以将operator 操作符看作是函数名,重载时只是返回值和参数列表的改变而已,是不是纸老虎?哈哈
重载运算符可被定义为普通的非成员函数或者被定义为类成员函数:
如果运算符被重载成为非成员函数,也就是一个global的全局函数,必须要将操作符的左右操作数都当作参数传进去:
例:Box& operator +(Box &x1,Box &2);
如果运算符被重载为类的成员函数,那么在传参的时候只需要传递操作符的右操作数,左操作数当作对象被传进去,对象的属性使用this指针进行访问,不需要我们显示传递。
1 #include <iostream> 2 using namespace std; 3 4 class Box 5 { 6 public: 7 8 double getVolume(void) 9 { 10 return length * breadth * height; 11 } 12 void setLength( double len ) 13 { 14 length = len; 15 } 16 17 void setBreadth( double bre ) 18 { 19 breadth = bre; 20 } 21 22 void setHeight( double hei ) 23 { 24 height = hei; 25 } 26 // 重载 + 运算符,用于把两个 Box 对象相加 27 Box operator+(const Box& b) 28 { 29 Box box; 30 box.length = this->length + b.length; 31 box.breadth = this->breadth + b.breadth; 32 box.height = this->height + b.height; 33 return box; 34 } 35 private: 36 double length; // 长度 37 double breadth; // 宽度 38 double height; // 高度 39 }; 40 // 程序的主函数 41 int main( ) 42 { 43 Box Box1; // 声明 Box1,类型为 Box 44 Box Box2; // 声明 Box2,类型为 Box 45 Box Box3; // 声明 Box3,类型为 Box 46 double volume = 0.0; // 把体积存储在该变量中 47 48 // Box1 详述 49 Box1.setLength(6.0); 50 Box1.setBreadth(7.0); 51 Box1.setHeight(5.0); 52 53 // Box2 详述 54 Box2.setLength(12.0); 55 Box2.setBreadth(13.0); 56 Box2.setHeight(10.0); 57 58 // Box1 的体积 59 volume = Box1.getVolume(); 60 cout << "Volume of Box1 : " << volume <<endl; 61 62 // Box2 的体积 63 volume = Box2.getVolume(); 64 cout << "Volume of Box2 : " << volume <<endl; 65 66 // 把两个对象相加,得到 Box3 67 Box3 = Box1 + Box2; 68 69 // Box3 的体积 70 volume = Box3.getVolume(); 71 cout << "Volume of Box3 : " << volume <<endl; 72 73 return 0; 74 }
有人可能会提出这样的疑问,对,那个人就是我,哈哈。“+”是双目运算符,为什么重载函数只有一个参数呢?实际上,运算符重载函数应当有两个参数,但是,由于重载函数是Complex类中的成员函数,因此有一个参数是隐含的,运算符函数是用this指针隐式的访问类对象的成员。可以看到operator+访问了两个对象中的成员,一个是this指针指向的对象中的成员,一个是形参对象中的成员。