Cxx primer-chap14-Overloaded Operations and Conversions

  1. 操作符重载能够让类这个类型像built-in类型一样自然,我们能够赋予操作符一些意义,使其代码逻辑流畅且自然:在这里插入图片描述
  2. 对于类而言,操作符重载其实就是函数:在这里插入图片描述,第一个形参对应第一个操作数,以此类推。
  3. 当操作符重载函数为类的成员函数时,左操作数隐式为当前对象this:在这里插入图片描述
  4. 如果操作符重载函数既不是成员函数,形参类型又不是类类型的话,那么就会和built-in类型的操作符冲突:在这里插入图片描述
  5. 不是所有的操作符都可以重载,同时我们也无法自创操作符:在这里插入图片描述,不论操作符的意义如何,其优先级、关联性和语言定义的一致:在这里插入图片描述
  6. 除了我们间接的调用操作符函数以显得直观外,我们可以显式地调用:在这里插入图片描述,放轻松,它就是函数。
  7. 因为操作符重载实际上就是函数调用,所以对于语言规定的一些操作符特性(例如&&||的短路特性,以及, ?:, &&, ||能够保证操作数的计算顺序)都会失效,因此突然让本应该的规则失效,会让用户不适应,综上,不推荐重载这些操作符:在这里插入图片描述
  8. 对于类而言,重载操作符需要三思而行:在这里插入图片描述,简单而言,可以认为操作符重载是对built-in 操作符逻辑意义延伸到自定义的类,而不是扭曲操作符本来的意义:在这里插入图片描述
  9. 至于将操作符重载函数定义成成员函数还是普通函数呢?建议尽可能为成员函数,除了一些对称操作符应该定义为普通函数会更加灵活,此外对于像<<>>的流操作的话,就必须定义成普通函数:在这里插入图片描述,所谓的对称操作符,例如:在这里插入图片描述
  10. 对于库中的类而言,它们也进行了操作符重载,例如IO库重载了<<>>以支持对built-in 类型进行流操作。为了支持自定义类的IO操作,我们必须对其进行重载,简单而言,对于插入操作符而言,其函数签名是:ostream &operator<<(ostream &os, const ClassType &item):在这里插入图片描述,而抽取操作符的函数签名是istream &operator>>(istream &is, ClassType &item)在这里插入图片描述,因为我们需要接收用户的输入,所以我们需要做好流的检查以保证接收对象内在状态一致:在这里插入图片描述
  11. 对于算术操作符和关系操作符,我们应该定义成普通函数以允许操作数的类型转换:在这里插入图片描述,此外应该在这里插入图片描述,原因就是快:在这里插入图片描述
  12. 对于相等操作符operator==而言,对于一些标准库算法是有必要的:在这里插入图片描述,同时关系操作符中,像operator<也很受欢迎:在这里插入图片描述,对于关系操作符而言,最重要的就是不能相互冲突:在这里插入图片描述,简单理解就是如果我们两个对象都不比对方小的话,那么我们认为两者就是相等的
  13. 额外的赋值运算符应该像copy constructorassignment operator一样定义为成员函数,同时它们的目的是允许其他类型直接赋值给该类的类型,因为同类型之间的赋值已经被copy constructorassignment operator包了:在这里插入图片描述,同时:在这里插入图片描述
  14. 对于operator[]而言:在这里插入图片描述
  15. 关于自增和自减操作符,因为它们改变类内部的状态,应该定义为成员函数。此外它们适合于迭代器类:在这里插入图片描述,前缀操作的函数签名:在这里插入图片描述,而后缀操作的函数签名需要和前缀进行区分:在这里插入图片描述,注意前缀版本返回引用(reference),后缀版本返回值(value)
  16. 关于解引用operator*和箭头->操作符,它们适合迭代器或指针类:在这里插入图片描述,这里重载的箭头操作符的返回类型:在这里插入图片描述应该为指针,具体细节很值得细究:在这里插入图片描述
  17. 因为类可以存储一些状态,所以对于重载了函数调用操作符的类对象(function objects)而言,其比普通函数更加灵活:在这里插入图片描述,此外一个类内部可以对该操作符就行操作符重载:在这里插入图片描述,使用场景是该类通常集合标准库里的算法:在这里插入图片描述
  18. 对于lambda表达式而言,他就是重载函数调用操作符的匿名类的匿名对象:在这里插入图片描述,对于带有捕获对象的lambda而言,情况会稍微复杂一些:在这里插入图片描述,同时其生成的类是否具有copy/move constructor取决于捕获的对象类型:在这里插入图片描述
  19. 至于是定义lambda还是函数对象,取决于问题复杂度:在这里插入图片描述
  20. 五种可调用对象,以及调用签名(函数类型):在这里插入图片描述,我们可以通过function将具有相同调用签名的函数对象看成是相同类型:在这里插入图片描述
  21. 进一步地将类这个类型看成自己人,允许类与其他类型进行相互转换:在这里插入图片描述,至于转换操作符operator type() const的具体要求:在这里插入图片描述,例如:在这里插入图片描述,结合测试:在这里插入图片描述,注意编译器每次只进行一次用户定义的类型转换,但是可以结合标准的类型转换一起使用。每个转换运算都应该返回相应类型的值(value):在这里插入图片描述
  22. 通常类应该谨慎重载操作符,但是类转换到bool是非常常见的,尽管这可能会发生意想不到的转换:在这里插入图片描述,为了防止意外情况发生,我们可以使用explicit关键字来防止隐式转换,但是对于那些用条件判断的表达式,编译器会自动使用explicit限定的类型转换进行隐式转换:在这里插入图片描述,实例:在这里插入图片描述
  23. 禁止相互甩锅:在这里插入图片描述,例如两个类相互转换:在这里插入图片描述,例如一个类定义了多个转换到算术类型的类型转换操作方式:在这里插入图片描述
  24. 关于转换和重载而言:在这里插入图片描述
  25. 对于重载函数而言,如果需要不同的用户定义的转换,那么标准定义的转换无法起到解除歧义的作用:在这里插入图片描述
  26. 如果类类型用于表达式的话,那么该操作符到底是类定义的重载操作符还是built-in版本,我们无法确定:在这里插入图片描述,就会造成相互重载的局面:在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ocodotial

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值