C++ 预约义的运算符,只能用于基本数据类型的运算:整型、实型、字符型、逻辑型等等,且不能用于对象的运算。可是咱们有时候又很须要在对象之间能用运算符,那么这时咱们就要重载运算符,使得运算符能用于对象之间的运算。函数
好比,在数学上,两个复数能够直接进行+、-等运算,但在C++中,直接将+或-用于复数对象是不容许的。有时会但愿,让对象也能经过运算符进行运算。这样代码就更简洁,也容易理解。code
例如:对象
complex_a 和 complex_b 是两个复数对象,求两个复数的和,但愿的能直接写成:complex_a + complex_b数学
这时咱们就须要对 +
号运算符进行重载。编译
运算符重载的实质就是函数重载,能够重载为普通函数,也能够重载为成员函数。运算符重载的基本形式以下:class
返回值类型 operator 运算符(形参表) { ... }
下面举个例子,实现对复数对象的 +
和 -
运算符重载:构造函数
class Complex // 复数类 { public: // 构造函数,若是不传参数,默认把实部和虚部初始化为0 Complex(double r = 0.0, double i = 0.0):m_real(r),m_imag(i) { } // 重载-号运算符,属于成员函数 Complex operator-(const Complex & c) { // 返回一个临时对象 return Complex(m_real - c.m_real, m_imag - c.m_imag); } // 打印复数 void PrintComplex() { cout << m_real << "," << m_imag << endl; } // 将重载+号的普通函数,定义成友元函数 // 目的是为了友元函数能访问对象的私有成员 friend Complex operator+(const Complex &a, const Complex &b); private: double m_real; // 实部的值 double m_imag; // 虚部的值 }; // 重载+号运算符,属于普通函数,不是对象的成员函数 Complex operator+(const Complex &a, const Complex &b) { // 返回一个临时对象 return Complex(a.m_real + b.m_real, a.m_imag + b.m_imag); } int main() { Complex a(2,2); Complex b(1,1); Complex c; c = a + b; // 等价于c = operator+(a,b) c.PrintComplex(); c = a - b; // 等价于 c = a.operator-(b) c.PrintComplex(); return 0; }
输出结果:数据类型
3,3 1,1
从上面的例子中,咱们能够知道重载为成员函数和普通函数的区别了:引用
c = a - b;
等价于 c = a.operator-(b)
c = a + b;
等价于c = operator+(a,b)
在上面的代码中,我把重载 +
号运算符的普通函数,在Complex
复数类中定义成了友元函数,目的是为了友元函数能访问对象的私有成员,不然会编译报错。im
这里还有个值得思考的问题:
Complex
对象而不是Complex &
呢?const Complex & c
常引用类型而不是Complex c
呢?// 重载-号运算符,属于成员函数 Complex Complex::operator-(const Complex & c) { // 返回一个临时对象 return Complex(m_real - c.m_real, m_imag - c.m_imag); }
首先先说一下参数表为何是const Complex & c
常引用类型,首先若是参数表若是普通的对象形式Complex c
,那么在入参的时候,就会调用默认的赋值(拷贝)构造函数,产生了一个临时对象,这会增大开销,因此就采用引用的方式,同时又为了防止引用的对象被修改,因此就定义成了const Complex & c
常引用类型。
再来讲一下返回值为何是普通Complex
对象,由于本次 - 号和 + 号运算符的函数执行以后,须要返回一个新的对象给到左值。