第十二章、运算符重载
运算符重载是指在自定义的类或普通函数对已有的运算符进行重新定义,在使用时用运算符代替成员函数进行操作。
1. 运算符的重载原理
在说明运算符重载之前我门先以数学中复数为例来封装一个 Complex 类,简化实现复数的加、减、乘等操作。
复数简介
每个复数都分为实部(real)和 虚部(image)两部分,如:(1+2i) 的实部是 1,虚部是 2。
他们的运算规则如下:
(1+2i) + (3+4i) = (4+6i);
(3+4i) - (1+2i) = (2+2i)
(1+2i) * (3+4i) = (1 * 3 + 1 * 4i + 3 * 2i + 2i*4i) = (-5 + 10i);
下面来封装一个 Complex 类,并实现成员函数 add、sub、mul 来实现负数的加、减、乘等操作。并通过 info 成员函数打印负数的值。
示例代码如下:
// filename: operator_demo.cpp
#include <iostream>
using namespace std;
class Complex {
public:
Complex(double r=0, double i=0): real(r), image(i){}
void info(){
cout << "(" << real << "+" << image << "i)\n";
}
Complex add(const Complex & right) const {
return Complex (
this->real + right.real,
this->image + right.image);
}
Complex sub(const Complex & right) const {
return Complex (
this->real - right.real,
this->image - right.image);
}
Complex mul(const Complex & right) const {
return Complex (
this->real * right.real - this->image * right.image,
this->real * right.image + this->image * right.real);
}
private:
double real;
double image;
};
int main(int argc, char * argv[]) {
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3;
c3 = c1.add(c2);
c3.info();
c3 = c2.sub(c1);
c3.info();
c3 = c1.mul(c2);
c3.info();
return 0;
}
编译和运行结果如下:
weimz@mzstudio:~$ g++ -o operator_demo operator_demo.cpp
weimz@mzstudio:~$ ./operator_demo
(4+6i)
(2+2i)
(-5+10i)
下面我们将成员函数 add 换成 operator +、sub 换成 operator -、mul 换成 operator *,然后 main 函数的 c1.add(c2) 替换成 c1 + c2、c2.sub(c1) 替换成 c2 - c1、c1.mul(c2) 替换成 c1 * c2
示例代码如下:
// filename: operator_add.cpp
#include <iostream>
using namespace std;
class Complex {
public:
Complex(double r=0, double i=0): real(r), image(i){}
void info(){
cout << "(" << real << "+" << image << "i)\n";
}
Complex operator +(const Complex & right) const {
return Complex (
this->real + right.real,
this->image + right.image);
}
Complex operator -(const Complex & right) const {
return Complex (
this->real - right.real,
this->image - right.image);
}
Complex operator *(const Complex & right) const {
return Complex (
this->real * right.real - this->image * right.image,
this->real * right.image + this->image * right.real);
}
private:
double real;
double image;
};
int main(int argc, char * argv[]) {
Complex c1(1, 2);
Complex c2(3, 4);
Complex c3;
c3 = c1 +c2;
c3.info();
c3 = c2 - c1;
c3.info();
c3 = c1 *c2;
c3.info();
return 0;
}
编译和运行结果同没有替换之前也是一样的。结果如下:
weimz@mzstudio:~$ g++ -o operator_add operator_add.cpp
weimz@mzstudio:~$ ./operator_add
(4+6i)
(2+2i)
(-5+10i)
可见,运算符实际就是函数,这个函数可以是类的成员函数,也可以全局函数。
运算符重载的语法
class 类名 {
返回类型 operator 运算符(形参列表) {}
};
运算符说明
- 运算符重载实质就是函数重载。
- 运算符重载只能使用现有的运算符,不能创造新的运算符。
- 运算符重载的参数的个数是固定的,类型可以自定义。
不支持重载的运算符
::作用域运算符?:条件运算符.成员访问运算符.*成员指针访问运算符