【C++学习记录】运算符重载

以“+”为例
作为成员函数重载:Entity operator+(Entity e)const;
作为全局函数重载:Entity operator+(Entity e1, Entity e2);
//需要将该函数声明为Entity类的友元

重载后的运算符使用:

Entity e1, e2;
e1 + e2;

作为成员函数重载,		e1 + e2;	等价于		e1.operator+(e2);
作为全局函数重载,	e1 + e2;	等价于		operator+(e1,e2);

自己的理解:重载函数可以看做是名称和用法有特殊规定的函数,写法也很自由。如上例中的对“+”的重载:函数形参除了Entity类以外可以是任何类型数据,可以是基本类型,也可以是其他自定义的类,只要能满足Entity+T的需求即可。同理,返回类型可以是void、bool、Entity&等类型。

因为运算符重载本质上是一个函数,所以必须注意传入的操作数顺序。
例如作为成员函数重载运算符“+”:

Entity operator+(int i)const; 

将Entity类对象(设为e)与一个int类型变量(设为i)相加时,必须以e+i的顺序相加。如果将int作为第一操作数:i+e,则会报错“没有与这些操作数匹配的运算符”。若想实现i+e,只能以全局函数的方式重载运算符“+”:

friend Entity operator+(int i, Entity e);

补充,另一种解决方法
可以在类中添加一个转换构造函数,与一个作为全局函数重载的operator+配合实现运算的对称
在Entity类中:

Entity(int i)
	:num(i)
{}
friend Entity operator+(const Entity &e1, const Entity &e2);

重载运算符的实现:

Entity operator+(const Entity& e1, const Entity& e2)
{
	return Entity(e1.num+ e2.num);
}

之后就能随意使用i+e和e+i的组合了。
编译器会尝试对int类型变量使用隐式转换转换为Entity类型,类似下方代码的效果。

Entity e1 = 1000;

重载的运算符操作数、优先级和结合性不变。
运算符重载的初衷是给类添加新的功能,方便类的运算,所以应优先考虑作为类的成员函数。
必须作为全局函数的运算符重载,通常是为了保证参数的对称性。

重载运算符“=”
当类中包含指向动态空间的指针时,常需要重载运算符“=”用于深拷贝。“=”只能作为成员函数重载。
一些注意事项:
1、返回值应声明为引用,函数体中总是使用“return *this;”返回;
2、如果形参声明为指向同类对象的引用或指针,应判别所指向的对象是否与被赋值的对象为同一对象;

if(&e == this) return *this;

3、被赋值对象应该先释放占用的内存空间或其他资源;

if(p) delete p;//p指向被赋值的Entity类对象

4、如果形参声明为指针或引用,通常应加上const修饰符;
5、如果形参声明为指针,应判别是否为空
6、重载了“=”的类通常也要自定义复制构造函数,反之亦然。
+=、-=、*=等复合赋值运算符也遵循上述注意事项。

增量运算符“++”
Entity类中与本例相关部分

class Entity 
{
private:
	int num;
public:
	Entity(int i)
		:num(i)
	{}
}

前缀++

Entity& operator++()
{
	num += 1;
	return *this;
}

//如果不将返回类型声明为引用,函数在返回时会创建一个新的Entitiy对象,且无法达成链式编程效果:++(++a)

后缀++
在这里插入图片描述

Entity operator++(int)
{
	num += 1;
	return Entity(num);
}

后缀++中的int并没有参与运算,是为了与前缀++作区分的占位参数。
与前缀++不同,后缀++中创建了一个新的Entity对象,并将其作为返回值。
C++本身的前缀/后缀++也是同样的道理,所以使用前缀++的效率较高。

二者作为全局函数重载时,唯一的操作数Entity对象必须作为第一参数。
friend Entity& operator++(Entity& e);
friend Entity& operator++(Entity& e, int);
重载运算符“- -”同理

重载关系运算符应返回bool

必须作为成员函数重载的运算符
=、[]、()、->

流运算符“>>”和“<<”
只能作为类的全局函数重载

犯过的错误
作为全局函数重载一个类的运算符,重载函数的形参中必须有一个该类对象作为参数(否则就没有作为运算符重载的必要了)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值