第十二章、运算符重载

运算符重载是指在自定义的类或普通函数对已有的运算符进行重新定义,在使用时用运算符代替成员函数进行操作。

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 类,并实现成员函数 addsubmul 来实现负数的等操作。并通过 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 + c2c2.sub(c1) 替换成 c2 - c1c1.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 运算符(形参列表) {}
};

运算符说明

不支持重载的运算符