运算符重载的宏观思考The Complex Class
运算符重载是C++中较C语言更加先进和灵活的地方之一,通过运算符重载,使运算符拥有了除了只能完成内置类型的运算操作之外的对于其他自定义类型的运算功能。这使得C++更加灵活,通俗,更加面向对象。
事实上运算符的重载不过是对函数名为“operator 运算符”的函数的定义,根据所操作的对象的不同,可以分为成员函数和友元函数两种定义方法。
C++中唯一的三目运算符不能重载,因此所有的运算符重载的形参都不会超过三个,又由于成员函数默认第一个形参必须是自定义类的对象并且默认绑定到*this指针,所以所有的重载为成员函数的运算符重载的形参都不会超过一个。如此说来,左操作数不是自定义的类型的对象是不能和自定义程序的对象运算了?所以我们引进了友元函数,当左操作数不是自定义类型时,可以定义友元函数,由两个形参,左形参是自由类型,右形参是自定义类型,返回自定义类型。这样就可以实现同一类型,不同类型之间的相互运算,并且不受对称性的干扰。算术用算符不存在对称性,有需要时要一一重载。
友元函数和成员函数并无差别,不过是多了声明和一个左类型对象这些形式上的东西,所以重载为友元函数或成员函数是灵活机动的。但有两个运算符的重载必须重载为友元函数,即输入输出运算符,这是两个包含在标准库istream和ostream中的两个运算符,不仅要重载为友元函数,而且返回值类型必须是istream或ostream,不能反回自定义类型因为二义性引起编译错误。其他除了必须重载为成员函数的赋值运算符(=)下标运算符([])调用运算符(())成员访问运算符(->)以及绝大多数重载为成员函数的复合求值运算符还有改变对象状态的自增自减运算符和解引用运算符,其他运算符的重载是非常自由的。
以The Complex Class为例
#include <iostream> #include <stdio.h> using namespace std; class Complex { double re; //real part of a complex number double im; //imaginary part of a complex number public: Complex() { re = 0; im = 0; } Complex(double a,double b = 0) { re = a; im = b; } Complex(const Complex& B) { re = B.re; im = B.im; } double real() const { return re; } double imag() const { return im; } friend ostream &operator<<(ostream &os,const Complex &c) { //输出运算符重载为友元函数,返回ostream类型 os << "(" << c.re << "," << c.im << ")"; return os; } friend istream &operator>>(istream &is,Complex &c) { //输入运算符重载为友元函数,右形参不加const,返回istream char i; is >> i >> c.re >> i >> c.im >> i; //在输入运算符重载中输入变量 return is; } Complex operator+(const Complex& B) { //一般重载,重载为成员函数,右形参为complex Complex temp; temp.re = re + B.re; temp.im = im + B.im; return temp; } Complex& operator+=(const Complex& B) { re += B.re; im += B.im; return *this; } Complex operator+(double num) { //一般重载,重载为成员函数,右形参为double Complex temp; temp.re = re + num; temp.im = im; return temp; } friend Complex operator+(double num,const Complex & B) { //重载为友元,左形参为double,返回complex Complex temp; temp.re = B.re + num; temp.im = B.im; return temp; } Complex operator-(const Complex& B) { Complex temp; temp.re = re - B.re; temp.im = im - B.im; return temp; } Complex operator-(double num) { Complex temp; temp.re = re - num; temp.im = im; return temp; } friend Complex operator-(double num,const Complex & B) { Complex temp; temp.re = num - B.re; temp.im = -B.im; return temp; } Complex& operator-=(const Complex& B) { //复合求值运算符,一般重载为成员函数, re -= B.re; im -= B.im; return *this; } Complex operator*(const Complex& B) { Complex temp; temp.re = re * B.re - im * B.im; temp.im = im * B.re + re * B.im; return temp; } Complex operator*(double num) { Complex temp; temp.re = re * num; temp.im = im * num; return temp; } friend Complex operator*(double num,const Complex & B) { Complex temp; temp.re = num * B.re; temp.im = B.im * num; return temp; } Complex& operator*=(const Complex& B) { double temp1 = re, temp2 = im; re = temp1 * B.real() - temp2 * B.imag(); im = temp1 * B.imag() + temp2 * B.real(); return *this; } Complex operator/(const Complex& B) { Complex temp; temp.re = (re * B.re + im * B.im) / (B.re * B.re + B.im * B.im); temp.im = (im * B.re - re * B.im) / (B.re * B.re + B.im * B.im); return temp; } Complex& operator/=(const Complex& B) { Complex temp; temp.re = (re * B.re + im * B.im) / (B.re * B.re + B.im * B.im); temp.im = (im * B.re - re * B.im) / (B.re * B.re + B.im * B.im); re = temp.re; im = temp.im; return *this; } Complex operator/(double num) { Complex temp; temp.re = re / num; temp.im = im / num; return temp; } friend Complex operator/(double num,const Complex & B) { Complex temp; temp.re = (num * B.re) / (B.re * B.re + B.im * B.im); temp.im = ((-num) * B.im) / (B.re * B.re + B.im * B.im); return temp; } bool operator == (const Complex& B) { //关系运算符重载为成员函数,右形参为complex类型 if (re - B.re < 1e-10 && im - B.im < 1e-10) { return true; } else { return false; } } bool operator != (const Complex& B) { if (re - B.re < 1e-10 && im - B.im < 1e-10) { return false; } else { return true; } } bool operator == (double num) { //关系运算符重载为成员函数,右形参为double类型 if (re - num < 1e-10 && im - 0.0 < 1e-10) { return true; } else { return false; } } bool operator != (double num) { if (re - num < 1e-10 && im - 0.0 < 1e-10) { return false; } else { return true; } } friend bool operator == (double num, const Complex& B) { //关系运算符重载成友元函数,左形参为double类型 if (B.re - num < 1e-10 && B.im - 0.0 < 1e-10) { return true; } else { return false; } } friend bool operator != (double num, const Complex& B) { if (B.re == num && B.im == 0) { return false; } else { return true; } } Complex operator-() { //取反运算符,改变对象装态,重载为友元函数 Complex temp; temp.re = -re; temp.im = -im; return temp; } };
用来调试的主程序:
#include<iostream> #include<string> #include"source.h" using namespace std; void f() { Complex a; cout << a << endl; Complex b = Complex(1,1.5); cout << b << endl; Complex c(3.5); cout << c << endl; c += a; cout << c << endl; c = c + a; cout << c << endl; c = c + 2.5; cout << c << endl; c = 2.5 + c; cout << c << endl; c -= a; cout << c << endl; c = c - a; cout << c << endl; c = c - 2.5; cout << c << endl; c = 2.5 - b; cout << c << endl; c *= b; cout << c << endl; c = c * b; //cout << c << endl; c = c * 2.5; //cout << c << endl; c = 2.5 * c; //cout << c << endl; c /= b; //cout << c << endl; c = c / b; //cout << c << endl; c = c / 2.5; //cout << c << endl; c = 2.5 / c; //cout << c << endl; c = -b; cout << c << endl; cout << (a==a) << endl; //output 1 cout << (a==0.0) << endl; //output 1 cout << (0.0==a) << endl; //output 1 cout << (a!=a) << endl; //output 0 cout << (a!=0.0) << endl; //output 0 cout << (0.0!=a) << endl; //output 0 //cout << a+2.5 << endl; //cout << 2.5+a << endl; //cout << a+b << endl; //c = a+2.5+a + b*2.5*b; while (cin >> c) { cout << c << endl; //cout << "(" << c.real() << "," << c.imag() << ")" << endl; } } int main() { f(); return 0; }