使对象的运算表现得和编译器内置类型一样
templateT sum(T a, T b) { return a+b;//a.operator+(b) }
- 如果T是编译器的内置类型的话,编译器对a+b是可以做的。
- 但是如果T是我们自定义的对象类型,a和b是两个对象,对象和对象之间该怎么相加???编译器是不知道的。
- 这里就要使用运算符的重载了。
return a+b;//a.operator+(b),a调用自己的加法函数,将b当成传进去
加法运算符的重载函数。
2、复数类的实现(运算符重载) 2.1、构造函数在这里,编译器能不能将一个整数变为一个对象?
- 这里涉及 实参类型 到 形参类型 的类型强制转换!
- 看编译器有没有提供带整数形参的构造函数 CComplex(int)的构造函数!
是可以的,因为我们写的构造函数可以是三种类型的构造函数:
2.2、 “+” 重载函数
我们要定义一个全局的加法函数,并且在类中定义为类的友元函数:
并且,现在可以将类内的 “+” 重载函数 成员方法屏蔽了,全局的 “+” 重载函数更好!
全局的 “+” 重载函数 可以实现 对象 “+” 对象、整数 “+” 对象、对象 “+” 整数
2.3、++和–前置后置运算符重载函数
operator++()表示前置++ operator++(int)表示后置++ 这个int只是为了区分,没有任何作用
2.4、“+=”运算符重载函数
2.5、“<<” 和 “<<”运算符重载
- 这个输出<<运算符重载,对象不在左边,所以不可以提供成员方法 (需要对象在左边进行调用),所以定义成全局方法
#includeusing namespace std; class CComplex { public: //CComplex() CComplex(20) CComplex(30, 30) CComplex(int r = 0, int i = 0) :mreal(r), mimage(i) {} //指导编译器怎么做CComplex类对象的加法操作 CComplex operator+(const CComplex &src) { //写法1: CComplex comp;//局部对象 comp.mreal = this->mreal + src.mreal; comp.mimage = this->mimage + src.mimage; return comp; //写法2: return CComplex(this->mreal + src.mreal, this->mimage + src.mimage);//对象的优化 } //后置++ CComplex operator++(int) { //方法1: //CComplex comp = *this; //mreal += 1; //mimage += 1; //return comp; //方法2: return CComplex(mreal++, mimage++); //返回的是局部对象,返回值用CComplex接收 } //前置++ CComplex& operator++() { mreal += 1; mimage += 1; return *this; //出函数,*this是存在的,不是局部对象,返回值用CComplex& } void operator+=(const CComplex& src) { mreal += src.mreal; mimage += src.mimage; } void show() { cout << "real:" << mreal << " image:" << mimage << endl; } private: int mreal;//实部 int mimage;//虚部 //这个全局的方法成了这个类的朋友,这个全局方法可以访问这个类的实部和虚部 friend CComplex operator+(const CComplex& lhs, const CComplex& rhs); friend ostream& operator<<(ostream& out, const CComplex& src); friend istream& operator>>(istream& in, CComplex& src); }; CComplex operator+(const CComplex& lhs, const CComplex& rhs)//加法的全局运算符重载 { return CComplex(lhs.mreal + rhs.mreal, lhs.mimage + rhs.mimage); } ostream& operator<<(ostream& out, const CComplex& src)//输出是从左向右运算的 { out << "mreal:" << src.mreal << " mimage:" << src.mimage << endl; return out; } istream& operator>>(istream& in, CComplex& src) { in >> src.mreal >> src.mimage; return in; } int main() { CComplex comp1(10, 10); CComplex comp2(20, 20); //comp1.operator+(comp2) 加法运算符的重载函数 CComplex comp3 = comp1 + comp2;//左边是对象,优先调用成员方法 ,成员方法没有的话就去找全局方法 comp3.show(); CComplex comp4 = comp1 + 20;//左边是对象,优先调用成员方法,成员方法没有的话就去找全局方法 //comp1.operator+(20) int->CComplex 编译器会找有没有CComplex(int)生成1个临时对象 ,然后进行相加 comp4.show(); //编译器做对象运算的时候,会调用对象的运算符重载函数(优先调用成员方法);如果没有成员方法 //就在全局作用域找合适的运算符重载函数 // 我们在全局提供 ::operator+(30, comp1) 30和comp1都当做实参传进去 CComplex comp5 = 30 + comp1;//30在里面必须要有趋势要做类型的转换!!! 无法调用成员方法的加法运算符重载函数 //看复数类型有没有带整型参数的构造函数来生成1个临时对象让lhs引用,就生成一个实部是30,虚部是0的临时对象 comp5.show(); //CComplex operator++(int) comp5 = comp1++; // ++ --是单目运算符 operator++()表示前置++ operator++(int)表示后置++ 这个int只是为了区分,没有任何作用 comp1.show(); comp5.show(); //CComplex operator++() comp5 = ++comp1; comp1.show(); comp5.show(); //void comp1.operator+=(comp2) ::operator+=(comp1, comp2) comp1 += comp2; //comp1.show();//对象信息的输出 //这个输出<<运算符重载,对象不在左边,所以不可以提供成员方法 ,所以定义成全局方法 //cout ::operator<<(cout, comp1) 流对象是不断放,取东西,是变化的,不能加const //void << endl; 因为要连续输出,不能用void作为返回值 //连续的输出,应该把cout返回:ostream& operator<<(ostream &out, const CComplex &src) //ostream &out,流对象是不断变化的,前面不能加const cout << comp1 << endl; cin >> comp1 >> comp2; cout << comp1 << comp2 << endl; return 0; }



