前言:本教程使用到的工具是vs2010;
目录
为什么要重载运算符?
运算符重载
重载++就一定要++吗?
重载后的运算符和普通运算符有什么区别?
总结
先看代码:
#include
#include class Number
{
public:int x;int y;Number(int x,int y){this->x = x;this->y = y;}
};int main()
{return 0;
}
我们定义了一个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运算符重载函数,但是普通运算符就是按照正常逻辑去操作内存;
结语:感谢大家观看,如果有错误请指正;讲的不好的地方也请提出来,谢谢大家!