一、什么是运算符重载
简单来讲就是对运算符赋予新的意义,但是又不能改变原有的含义,它本身也就是一个函数。运算符重载的本质是以函数的方式来体现。
二、运算符重载有几种
1、按照作用域来划分,有全局操作符重载函数和成员函数操作符重载函数。
2、按照操作数个数来划分,有单目运算符重载和双目运算符重载。
通常来讲,往往把输入流和输出流运算符改写为全局操作符重载函数,普通的运算符改写为成员函数操作符重载函数。如果想要使用成员函数来重载输出流《 和 输入流》,必须在C++库中对应的类加入这个重载的成员函数,不建议使用。
三、运算符重载的特性
1、不能新增运算符,只能对已有的C++运算符进行重载。
2、不能改变操作数的个数,运算符重载后仍是原有操作数个数。
3、尽量不改变语义,应当使重载运算符功能是类似相同。
4、并不是所有的运算符都可以重载,以下5个运算符不能重载作用域运算符::,成员访问运算符.,类型长度运算符sizeof(),成员指针运算符.*,条件运算符?:。
四、怎么实现运算符重载
采用普通函数的调用方式来调用运算符重载函数,基本语法如下:
// 关键字operator不能省略 // 函数名:operator 运算符 // 参数列表:操作数的个数受原有运算符的操作数个数限定 返回值 operator 运算符(参数列表) { // 重载函数体 }
五、案例
1、运算符重载的简单使用
#include <iostream> using namespace std; // 复数类 class Complex { private: int a; // 实部 int b; // 虚部 public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } void show() { if(b < 0) { cout << a << b << "i" << endl; } else { cout << a << "+" << b << "i" << endl; } } // 重载运算符+ Complex& operator + (const Complex& op) { static Complex temp; temp.a = this->a + op.a; temp.b = this->b + op.b; return temp; } // 重载运算符- Complex& operator - (const Complex& op) { static Complex temp; temp.a = this->a - op.a; temp.b = this->b - op.b; return temp; } // 重载运算符* Complex& operator * (const Complex& op) { static Complex temp; temp.a = this->a*op.a - this->b*op.b; temp.b = this->a*op.b + this->b*op.a; return temp; } // 重载运算符 / Complex& operator / (const Complex& op) { static Complex temp; int x = op.a*op.a + op.b*op.b; temp.a = (this->a*op.a + this->b*op.b)/x; temp.b = (this->b*op.a - this->a*op.b)/x; return temp; } bool operator == (const Complex& op) { return (this->a == op.a && this->b == op.b); } }; int main() { Complex A(1, 2); Complex B(1, 2); if(A == B) { cout << "A == B" << endl; } Complex C = A + B; cout << "C = "; C.show(); Complex D = A - B; cout << "D = "; D.show(); Complex E = A * B; cout << "E = "; E.show(); Complex F = A / B; cout << "F = "; F.show(); return 0; }
2、全局操作符重载示例
#include <iostream> using namespace std; // 复数类 class Complex { private: int a; // 实部 int b; // 虚部 public: Complex(int a = 0, int b = 0) { this->a = a; this->b = b; } void show() { if(b < 0) { cout << a << b << "i" << endl; } else { cout << a << "+" << b << "i" << endl; } } // 全局操作符重载,重载输入流和输出流,为了方便通常声明friend友元函数 friend ostream& operator << (ostream & output, const Complex & other); friend istream& operator >> (istream & input, Complex & other); }; // 可以改为以下定义,但是后面不能连续输入对象,即cout<< A << endl;是非法的,只能cout << A; // void operator << (ostream & output, const Complex & other) ostream& operator << (ostream & output, const Complex & other) { if(other.b < 0) { output << other.a << other.b << "i"; } else { cout << other.a << "+" << other.b << "i"; } return output; } // 可以改为以下定义,但是后面不能连续输入对象,即cin>>A>>B;是非法的,只能cin>>A; cin>>B; // void operator >> (istream & output, const Complex & other) istream& operator >> (istream & input, Complex & other) { input >> other.a >> other.b; return input; } int main() { Complex A; Complex B; cin >> A >> B; // 可以连续输入类对象 cout << "A = "; A.show(); cout << "B = " << B << endl; return 0; }
3、[]运算符和()运算符
#include <iostream> using namespace std; class Test { private: int *a; int len; public: Test(int len = 1) { this->len = len; if(len <= 0) { cout << "len is less than 0" << endl; return; } a = new int[len]; } ~Test() { if(a != nullptr) { delete [] a; a = nullptr; } } // 重载[]运算符函数 int& operator[](int index) { return a[index]; } // 重载()运算符函数,变成所谓的仿函数,可以用类对象来作为函数名 void operator()(int len) { for(int i = 0; i < len; i++) { cout << a[i] << " "; } cout << endl; } }; int main() { Test temp(5); for(int i = 0; i < 5; i++) { temp[i] = i+1; // 像数组那样来操作 } temp(5); // 像调用函数那样来操作 return 0; }
六、总结
运算符重载通常是为了更加方便的操作类对象,但是并不是所有的运算符都可以重载,重载的运算符应该尽量跟原来运算符的含义相似,同时不能创造新的不属于C++的运算符。