运算符重载探究


意义

  因为简单的加减乘除符号不能满足我们的需求,例如如果我们要将两个类相加(可能只是针对类中的数据成员相加),常规的加法运算符显然时不能满足需求的;

使用

  需要熟悉一下使用重载运算符的基本用法:

class Time

{

     Time operator+(const Time & t) const;

};

Time Time:operator+(const Time & t) const

{

    ...

}

  使用时,由于我们已经重载了+运算符,所以有以下结论:

Time t1;

Time t2;

Time total = t1.operator+(t2);

  等价于

Time total = t1 + t2;

  需要注意的是,左侧的运算符应该是调用对象;

  事实上,类方法也可以实现大部分的运算符重载实现,比如我们可以定义一个sum( )的函数来实现类相加之和,但是运算符重载明显要方便的多;

限制

  但是也需要明白,重载运算符也是有相关限制的,否则,运算符的使用将会变得混乱不堪;

  1. 重载后的运算符必须至少有一个操作数是用户定义的类型,大多数情况下,我们其实都是针对某个类进行重载运算符,但是也不能排除有程序员想利用c++规则针对系统类型的运算符进行重载,例如,如果把+号重载为int型的减号,岂不是很奇怪,这将与系统冲突,当然,我们可以将自定义的类型重定义为这种使用,没有关系;
  2. 不能违反我们所重载运算符的语法规则,例如加号就是针对两个数据,即使我们将其重载为1个数据的运算,也是不允许的;
  3. 不能创建新的运算符;虽然这一点感觉限制了创造性,但是还是可以理解,否则千奇百怪的运算符看起来也会很奇怪;
  4. 大部分运算符都可以通过成员函数或非成员函数进行重载,但是部分运算符只能通过成员函数重载;包括: = 、()、[ ]、->。
  5. 有部分运算符并不支持重载,包括: . 和 .* 和 ?: 和 :: 和 sizeof 和 typeid。

非成员函数的运算符重载

  以上都是以成员函数形式实现的运算符重载,但是实际上也可以以非成员函数定义运算符重载。

  我们可以实现单用户自定义成员运算符重载,比如,一个类乘以一个常量。那么有如下形式:

Time Time::operator*(double n) const;

  针对运算符重载提出这样有个问题,如何将A = 2.75 * B通过重载*运算符实现?

  显然,如果用一般的重载方法恐怕很难实现,因为重载要求左侧为调用对象,那么如何解决呢?这就需要我们使用非成员函数来重载运算符了!

A = operator*2.75,B);

  非成员函数重载实现如下:

Time operator*double m,const Time&t);

  但还有一个问题,我们直到,2.75乘以一个类,当然不是传统意义上的直接乘以,而是与这个类中的某个成员作用,那么问题来了,类的数据成员一般是私有的,该怎样获取呢?这就要用到友元函数。

  友元函数的意义在于使我们直接使用某个类中的私有成员,即使这个函数其实并不从属于这个类;

  我们可以像下面这样在类中声明一个友元函数。

class Time
{
public:
	...
	friend Time operator*double m,const Time & t);
}

Time operator*double m,const Time & t)
{
	...
}

  需要注意的是:

  • 一定要在类声明中声明该友元函数,同时加上关键字friend,这样才能保证友好关系真正建立;
  • 该友元函数虽然并非这个类的成员函数,但其权限与这个类的成员函数权限完全相同;
  • 声明中我们带着关键字friend,但是定义中则没有必要;

成员函数还是非成员函数?

  通过友元函数,我们实现了非成员函数对运算符的重载,当然,也可以通过成员函数来实现这个重载,那么,二者之间到底存在什么区别呢?二者的使用场景又有何不同呢?

  非成员版本重载运算符所需的形参数目与运算符使用的操作数目相同,而成员版本所需的参数则要少一个,因为其中有一个this指针被隐式传递了;即: T1 = T2.operator+(T3); 等于 T1 = operator(T2,T3);

  一般来说,非成员函数与成员函数的运算符重载没有多大区别,都是可以的,但是根据类设计,定义非成员函数可能更好,但是需要注意的是:我们只能在两者之间选择一种实现,否则两个定义可能与同一个表达式匹配,从而造成二义性错误。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值