1 #include<iostream> 2 using namespace std; 3 class Test { 4 friend Test addTest(Test &obj1, Test &obj2); 5 // friend Test operator+(Test &obj1, Test &obj2); 6 public: 7 Test(int a = 0, int b = 0) 8 { 9 this->a = a; 10 this->b = b; 11 } 12 void display() 13 { 14 cout << "a:" << a << " b:" << b << endl; 15 } 16 public: 17 Test operator+(Test &obj) 18 { 19 Test temp(this->a+obj.a,this->b+obj.b); 20 return temp; 21 } 22 private: 23 int a; 24 int b; 25 }; 26 Test addTest(Test &obj1, Test &obj2) 27 { 28 Test temp(obj1.a + obj2.a, obj1.b + obj2.b); 29 return temp; 30 } 31 //Test operator+(Test &obj1, Test &obj2) 32 //{ 33 // Test temp(obj1.a + obj2.a, obj1.b + obj2.b); 34 // return temp; 35 //} 36 int main() 37 { 38 /* 第一个测试 39 Test t1(1, 2), t2(3, 4); 40 Test t3 = addTest(t1, t2); 41 Test t4 = t1+t2;//err 42 t3.display(); 43 */ 44 45 /* 第二个测试 46 Test t1(1, 2), t2(3, 4); 47 Test t3 = operator+(t1, t2); 48 Test t4 = t1+t2; 49 t3.display(); 50 t4.display(); 51 */ 52 /*第三个测试 53 Test t1(1, 2), t2(3, 4); 54 // Test t3 = operator+(t1, t2);err 55 Test t3 = t1.operator+(t2); 56 Test t4 = t1+t2; 57 t3.display(); 58 t4.display(); 59 */ 60 cout << "hello world! "; 61 return 0; 62 }
根据不同重载方式有不同的调用方式。全局函数重载运算符,成员函数或者友元函数重载运算符。
重载运算符是具有特殊名字的函数,它由关键字operator和其后要定义的运算符共同组成。和其他函数一样,重载的运算符也包含返回类型、参数列表以及函数体。
重载运算符的参数数量应该与运算符作用的对象数量一样多,一元运算符一个参数,二元运算符两个参数。对于二元运算符,左侧运算对象传递给第一个参数,而右侧运算对象传递给第二个参数。除了重载的函数调用运算符operatoe()之外,其他重载运算符不能含有默认实参。
如果一个运算符是成员函数,则它的第一个(左侧)运算对象绑定到隐式的this指针上,因此,成员运算符函数的(显式)参数数量比运算符的运算对象少一个。
对于一个运算符函数来说,它或是类的成员,或者至少含有一个类类型的参数:
int operator+(int,int)//错误,不能为int重定义内置的运算符
我们只能重载已经有了的运算符而不能发明新的运算符,我们可以重载大部分运算,但不是全部。
对于一个重载的运算符来说,其优先级和结合律与对应的内置运算符保持一致。
通常情况我们不应该重载逗号,取地址,逻辑与和逻辑或运算符。
运算符重载本质是函数调用,所以关于运算对象的求值顺序的规则无法应用到重载的运算符上。而&&和||的短路求值属性也无法保留,因此不建议重载他们。对于逗号和取地址运算符,c++语言已经定义了它们用于类类型对象时的特殊含义,这一点与大多数运算符都不相同。这两种运算符已经有了内置的含义,所以一般来说不应该被重载,否则它们的行为将异于常态,从而导致类的用户不好适应。
当你设计一个类时,首先应该考虑这个类提供哪些操作,再思考到底应该把每个类操作设成普通函数还是重载运算符。
如果执行IO操作,则定义一维运算符使其与内置类型IO保持一致;
如果有了operator==通常应该有operator!=,有了 < 通常应该有 > ;
重载运算符的返回类型通常情况下应该与其内置版本的返回类型兼容:逻辑运算符和关系运算符应该返回bool,算术运算符应该返回一个类类型的值,赋值运算符和复合赋值运算符则应该返回左侧对象的一个引用。