• 【C++】运算符重载


     前言:本教程使用到的工具是vs2010

    目录

    为什么要重载运算符? 

    运算符重载

    重载++就一定要++吗?

    重载后的运算符和普通运算符有什么区别?

    总结


    为什么要重载运算符? 

    先看代码:

    1. #include
    2. #include
    3. class Number
    4. {
    5. public:
    6. int x;
    7. int y;
    8. Number(int x,int y)
    9. {
    10. this->x = x;
    11. this->y = y;
    12. }
    13. };
    14. int main()
    15. {
    16. return 0;
    17. }

    我们定义了一个Number类,有两个成员;和一个构造函数,为两个成员赋值;

    然后我们定义一个函数,来返回两个数值中的最大值,如下:

    然后我们定义两个变量进行比较,并输出最大值,如下:

    我们的目的达到了,成功的返回了两个int类型的最大值

    如果我们想要比较double类型、char类型,都很简单,直接>号<号比较就行了;

    但是如果我们想要比较两个Number类型的对象呢?

    仔细想一下,我们该怎么办?

    首先,第一种方法,直接在类中写一个这样的函数:

    定义两个对象,并初始化如下:

    调用者n1,传入实参对象n2,如果n1>n2会返回1(true),如果不大于(<=)就返回0(false):

    定义一个bool类型接收,int也行:

    打印输出:

    n1的x和y都小于了n2,所以为0,没有问题;

    但是这样通过函数的调用来完成类对象的比较,看起来也不是很舒服 

    那么有没有办法,能让类的对象像普通变量一样进行比较呢?

    有的

    就是我们下面要讲的运算符重载;

    我们现在可以说一下为什么要重载运算符了,就是为了我们的对象使用起来能像普通变量那么方便;

    运算符重载

    运算符重载语法如下:

    返回值类型 operator待重载运算符(参数列表)

    {

            

    }

    运算符重载一般定义在类中,因为一般我们重载运算符就是为了类的对象能够使用该运算符

    我们首先来重载一下大于号 (>);

    如下:

    这里只能传递一个参数,因为>号是双目运算符,只能有左操作数和右操作数,然而类的成员函数已经有this指针(左操作数)了

    我们定义两个对象,进行比较,如下:

    我们有两种比较方式,第一种:

    还是和我们刚刚那样进行函数调用,但是如果这样写,那么重载也就毫无意义了

    所以我们还可以,这样写:

    只要我们在类中重载了>号,那么我们类的对象就可以直接使用>号进行比较,当然没有重载的符号依旧不可以使用,如下:

    没重载的是不行的;

    重载++就一定要++吗?

    再举例: 

    正常情况下我们普通变量都是可以直接++的,如下:

    那么类的对象能不能++呢?

    当然可以,重载嘛,如下:

    再次注意这里,我们的++是单目运算符,因为类的成员函数有this指针这个参数,所以不能再添加参数了;

    我们加一下试试:

    没有问题

    但是我有一个问题,我们重载的++运算符就一定要是++吗?

    当然不是

    如下:

    我们完全可以这样写,我们只是重载了++操作符,但是他也只是个函数啊,函数的内容我们想怎么写就怎么写

    我们运行一下: 

    没问题

    谁说++就一定要加了?谁说++就一定要加1?

    这也就是为什么计算机中1+1不一定等于2,因为这个操作符是别人自己按照他的思维来重载的,我们当然也可以按照自己的思维来写,++我们写个减1,但是没必要,一般情况下我们还是遵守计算机的算法来写,不要乱写,没什么好处;

    重载后的运算符和普通运算符有什么区别?

    最后我们来看一下,我们使用的++他难道真的就是一个符号吗?重载++操作符后的++和普通变量的++又有什么区别呢?

    我们先来看普通变量,如下:

    像我这样写代码,在这条没用的汇编这里打个断点,然后编译、调试,最后alt+8转到反汇编,如下:

    普通变量的++分为三步骤:

            1、将临时变量t从内存中取出来,放到eax寄存器里;

            2、使用add命令将eax寄存器中的值+1;

            3、将+1后的值放回临时变量t的那块内存;

    再看重载的++(对象++);

    我们先把operator++这个函数改回来,然后像我这样写代码下断点:

    编译、调试、alt+8:

    两个步骤:

            1、将对象n这个地址放到ecx寄存器里,前面的课我有说过,ecx一般就是存放this指针的,那么这一步的意思就是,将n的地址看成是this指针,放到ecx里(寄存器传参);

            2、调用Number::operator++函数;

    可以看到,我们自己重载的++,编译器最终还是调用的函数,并没有像我们普通变量那样,将值取出来+1再放回去; 

    思考一下这是为什么呢?

    因为编译器根本不知道我们的operator++(重载++运算符的函数)里边写的是什么,我们刚刚也说了,我们可以随便写,想写什么写什么;既然编译器不能确定我们写的是什么,他当然不能将我们的值取出来+1再放回去啊,如果编译器这样做的话,我们的重载还有什么意义呢?

    所以我们看到的对象++,并不是真正的++,他最终还是调用的函数(operator++函数);

    总结

            1、我们之所以要重载运算符,就是为了类的对象使用运算符也能和普通变量一样方便;

            2、运算符重载的语法是: 返回值类型 operator 待重载运算符(参数列表) { }

            3、重载的运算符不一定非要是我们认知里的操作,比如重载的++不一定非要++,也可以--;

            4、重载后的运算符和普通运算符的区别在于,重载后的运算符使用的时候还是调用operator运算符重载函数,但是普通运算符就是按照正常逻辑去操作内存;

    结语:感谢大家观看,如果有错误请指正;讲的不好的地方也请提出来,谢谢大家!

  • 相关阅读:
    dflow入门5——Big step & Big parameter
    双二面角耦合力场项的计算
    JavaScript:实现使用 2 个堆栈形成队列算法(附完整源码)
    Java——聊聊JUC中的CAS原理
    如何进行DAP-seq的数据挖掘,筛选验证位点
    并发线程特性-可见性和有序性
    奇迹1.03H服务端开服架设文件Data文件详解
    如何用度量数据驱动代码评审的改善
    力扣题解22-25
    java开发者工具IDEA自定义设置主题/字体/字号大小
  • 原文地址:https://blog.csdn.net/qq_52572621/article/details/127869796