一、重载运算符
+ - * / % ^ & | ~ ! = < > += -= *= /= % ^= &= |= << >> >>= <<= == != <= >= && || ++ -- ->* ‘ -> [] () new delete new[] delete[]
不能用友元函数重载的运算符:
= () [] ->
不能重载的运算符:
.* :: ?: sizeof
二、重载运算符的限制
不改变运算符的优先级
不改变运算符的结合性
不改变运算符所需要的操作数
不能创建新的运算符
三、运算符重载规则
(1)运算符成员函数只能定义运算符的含义,不能改变运算符的优先级和结合顺序.
(2)运算符重载时,不能改变其目数.
(3)运算符函数即可在类中定义,也可以在类外定义.在类外定义时,它至少应有一个相应类的参数.
(4)无论是在类中定义的运算符成员函数,还是在类外定义的运算符函数,都可以进行重载。也就是说可以定义多个同名的运算符函数。但其参数类型应有差别,否则会产生二义性。
四、成员运算符函数与友元运算符函数
成员运算符函数
成员函数的参数个数比原来的操作数少一个(后置单目运算符除外),这是因为成员函数用this指针隐式地访问了类的一个对象,它充当了运算符函数最左边的操作数。因此:
(1) 双目运算符重载为类的成员函数时,函数只显式说明一个参数,该形参是运算符的右操作数。
(2) 前置单目运算符重载为类的成员函数时,不需要显式说明参数,即函数没有形参。
(3) 后置单目运算符重载为类的成员函数时,函数要带有一个整型形参。
友元运算符函数
友元函数由于没有隐含的this指针,因此操作数的个数没有变化,函数的参数与操作数自左至右一一对应。
五、两种重载形式的比较
(1) 一般情况下,单目运算符最好重载为类的成员函数;双目运算符则最好重载为类的友元函数(操作数类型不相同时,必须使用友元函数)。
(2) 类型转换函数只能定义为一个类的成员函数而不能定义为类的友元函数。
(3) 若一个运算符的操作需要修改对象的状态,选择重载为成员函数较好。
(4) 若运算符所需的操作数(尤其是第一个操作数)希望有隐式类型转换,则只能选用友元函数。
(5) 当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(或者是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,或者是一个内部类型的对象,该运算符函数必须作为一个友元函数来实现。
(6) 当需要重载运算符具有可交换性时,选择重载为友元函数。
六、两种重载调用方式
代码示例:
1 #include<iostream> 2 using namespace std; 3 4 class Complex 5 { 6 private: 7 int a; 8 int b; 9 /* 友元函数方式实现操作符(-)重载 */ 10 friend Complex operator+(Complex c1, Complex c2); 11 12 public: 13 Complex(int a, int b) 14 { 15 this->a = a; 16 this->b = b; 17 } 18 /* 成员函数方式实现操作符(-)重载 */ 19 Complex operator-(Complex c) 20 { 21 Complex tmp(this->a - c.a, this->b - c.b); 22 return tmp; 23 } 24 void print() 25 { 26 cout << a << " + " << b << "i" << endl; 27 } 28 }; 29 30 /* 友元函数的实现 */ 31 Complex operator+(Complex c1, Complex c2) 32 { 33 Complex tmp(c1.a + c2.a, c1.b + c2.b); 34 return tmp; 35 } 36 37 int main() 38 { 39 Complex c1(1, 2), c2(3, 4); 40 41 cout << "***用成员函数实现测试操作符 (-) ***"<< endl; 42 Complex c3 = c2.operator-(c1); 43 cout << "c3 = c2.operator-(c1) = " ; 44 c3.print(); 45 46 Complex c6 = c2 - c1; 47 cout << "c6 = c2 - c1 = " ; 48 c6.print(); 49 50 cout << "***用友元函数实现操作符 (+) *** "<< endl; 51 Complex c4 = c1 + c2; 52 cout << "c4 = c1 + c2 = "; 53 c4.print(); 54 55 Complex c5 = operator+(c1,c2); 56 cout << "c5 = operator+(c2,c1) = "; 57 c5.print(); 58 59 return 0; 60 }
双目成员函数调用 :
aa @ bb; //隐式调用
aa.operator@(bb); //显式调用
双目友元函数调用 :
aa @ bb; //隐式调用
operator@(aa,bb); //显式调用