11_运算符重载

11 运算符重载

自定义类型如下

class Number
{
    private:
        int x;
        int y;
    public:
        Number(int x, int y)    // 构造函数给私有变量赋值
        {
            this->x = x;
            this->y = y;
        }
};

然后我们创建两个对象

#include "stdafx.h"
#include <stdlib.h>
#include <windows.h>

int main(int argc, char* argv[])
{
    Number n1(1,1), n2(2,2);

    return 0;
}

假设我需要当前这个类里面有个新的成员函数, 这个成员函数可以比较与另外一个 Number 对象的大小

比如 x 大于另外一个 Number 对象的 x, y 大于另外一个对象的 y, 那么我们就认为这个对象大于另一个对象

我们需要这个功能, 好办, 我们直接在这个类里面定义一个函数

class Number
{
    private:
        int x;
        int y;
    public:
        Number(int x, int y)    // 构造函数给私有变量赋值
        {
            this->x = x;
            this->y = y;
        }

        int Max(Number& n)  // 因为直接传结构体的话, 在内存中要复制效率不高, 所以这里传一个引用类型
        {
            return this->x > n.x && this->y > n.y;  // 表达式结果最终只能会是 0 或 1
        }
};

写完了之后我们可以做一个测试 :

int main(int argc, char* argv[])
{
    Number n1(1,1), n2(2,2);

    int r = n1.Max(n2); // n1 和 n2 比, 这里用 n1 的成员函数

    return 0;
}

r 的结果为 0, 没有问题

但是这里面有个问题, 就是我们这个函数的返回值, 它仅仅是为了存一个状态, 0 或者 1, 我们现在用一个 int 类型有点浪费, 那么可不可以有一个更简单的类型来存储这个结果呢

答案是可以的, C++ 里面有一种类型叫作布尔类型 (bool), 布尔类型的值只有两种, 一种是 true, 一种是 false

我们可以看看反汇编, 看看 bool 类型到底什么样, 可以看到它就是个 char 类型, 为 true 的时候返回值为 1, 为 false 的时候返回值为 0

C++ 之所以存在这种类型, 就是为了使用方便, 所以这里我们的成员函数就没必要用 int 了

bool Max(Number& n)
        {
            return this->x > n.x && this->y > n.y;
        }
int main(int argc, char* argv[])
{
    Number n1(1,1), n2(2,2);

    bool r = n1.Max(n2)

    return 0;
}

这个代码没有问题

但是有一点, 我们以前学基本类型的时候, 比较大小的时候, 只需要用一个符号 > < 就搞定了, 但是这里我们比较大小的时候却需要一个函数来实现它.

那如果我们这里对象比较大小的时候, 也有这么一个符号, 那是不是很好

2 运算符重载 : ++ -- + - * / > < 等等

class Number
{
    private:
        int x;
        int y;
    public:
        Number(int x, int y)
        {
            this->x = x;
            this->y = y;
        }

        Number operator++();
        Number operator--();
        Number operator+(const Number& p);
        Number operator-(const Number& p);
        Number operator*(const Number& p);
        Number operator/(const Number& p);
        bool operator>(const Number& p);
        bool operator<(const Number& p);
        bool operator==(const Number& p);
};

C++ 编译器遇到 operator 的时候, 它就知道你要做的是运算符重载, 重载的运算符跟在后面, 中间有没有空格无所谓

然后我们只用做一件事情, 把 Max() 改成 operator>()

bool operator>(Number& n)
{
    return this->x > n.x && this->y > n.y;
}

改了以后呢, 我们就可以直接用 > 比较大小了

int main(int argc, char* argv[])
{
    Number n1(1,1), n2(2,2);

    bool r = n1 > n2;

    return 0;
}

然后我们编译通过了

其实我们做的事情, 无非就是告诉编译器, 现在这个大于号 > 就相当于 Max() 函数

这个我们称为运算符重载

运算符重载本质上就是给运算符绑定一个具体的函数

我们看看反汇编代码

;bool r = n1 > n2
lea     eax, [ebp-10h]
push    eax
lea     ecx, [ebp-8]
call    @ILT+15(Number::operator>) (00401014)
mov     byte ptr [ebp-14h], al

可以看出来, 它就是一个函数

运算符重载就只是为了写代码的时候方便, 底层没有任何差别