重载运算符是c++的一个重要特性,使用运算符重载,程序员可以把c++运算符的定义扩展到运算分量是对象的情况
运算符重载的目的是使c++代码更直观,更易读
在c++中除了下面几种运算符外,系统预定义的运算符都能够被重载
重载运算符要保持原运算符的以下特性不发生改变:
运算符重载的实质是通过定义一个函数实现的
运算符重载不能创造新的运算符
在c++中,运算符重载是通过运算符重载函数实现的,运算符重载函数一般有以下两种形式
返回值为一个该类对象的引用,前置自增(++obj),自增结果会返回给调用的类对象,不会生成副本
返回值为引用也解决了连续自增的问题
在此引出一个新问题,运算符重载的本质是重载成员函数,所以调用时obj++
也可以等价于obj.operator++();
,他们的作用是相同的
为什么返回的是副本而不是*this呢?主要是为了解决赋值运算符的问题
后置++的调用也等价于obj.operator++(1);
前置自减(--obj)和后置自减(obj--)同理
为什么出现了一个备份呢?试想一下,如果出现一下的代码obj1 + obj2
,结果为两个类对象相加的值。但值并没有被接收,类对象obj1和obj2本身并没有改变。所以应该返回备份的值而不是原来的*this对象
这里的参数是不是const &意义不大,如果不是则会将实参入栈,会多花费一点资源而已
同样的,上面的示例代码是重载了两个类对象的+运算符,且+运算符的本质是obj.operator+(1);
,1会被先转换成MyClass
类,在进行相加
试想一下,如果形如obj + 1 + 2 + 3
时,它调用的运算符重载函数是什么样子呢?
以上两者等价
重载+=运算符不需要返回值,它直接将结果赋值给调用的类对象
实参为类对象同理,代码如下
+=运算符的实质是obj.operator+=(1);
,与其他运算符的本质相同
在重载运算符时,可以使用转换构造减少代码量,不用给不同类型的实参写不同的重载函数了
其他的运算符如*
,*=
,/
,/=
的重载也同理
有一些特殊运算符可以用成员函数的形式重载
友元函数形式的运算符重载经常用在形如1+obj
发生的时候,因为我们没有办法重载int类,所以只能在本类中重载。但成员函数重载的调用者是类对象,所以便只能用友元实现重载
友元函数的重载其参数顺序和调用顺序一致,也就是说,可以通过只实现一个友元函数的重载加转换构造即可完成所有类型的运算符重载。
减少了代码量,增强了复用性
其他的运算符同理
友元也可以用来重载++
类似的单目运算符,代码如下
能使用operator++(obj)
调用,也能通过++obj
调用
友元能重载一些特殊的运算符
最常用的当属<<
、>>
输入输出流的重载,也可以用友元实现
当输出形如cout << obj3 << "this is a test";
时,需要向重载后的流中继续输出,所以返回值的类型为ostream&
返回值为istream&
类型,注意事项和>>运算符一致
小弟博客:knocked.github.io大佬求关照!勿喷万分感谢
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2019-10-9 09:54
被Knocked编辑
,原因: