第十四章 重载运算与类型转换

来源:互联网 发布:阿里云主机干什么的 编辑:程序博客网 时间:2024/05/23 19:14
  1. 重载的运算符是具有特殊名字的函数:它们的名字由关键字 operator 和其后要定义的运算符号共同组成。
  2. 我们只能重载已有的运算符,而无权发明新的运算符。
  3. 逻辑与运算符、逻辑或运算符和逗号运算符的运算对象的求值顺序规则无法保留下来。 && 和 || 运算符的重载版本也无法保留内置运算符的短路求值属性,两个运算对象总是会被求值。因此不建议重载这些运算符。
  4. 因为逗号运算符和取地址运算符已经有了内置的含义,所以一般来说它们不应该被重载,否则它们的行为将异于常态,从而导致类的用户无法适应。
  5. 如果类含有算术运算符或者位运算符,则最好也提供对应的复合赋值运算符。
  6. 下面准则有助于我们在将运算符定义为成员函数还是普通的非成员函数做出抉择:
        ① 赋值(=)、下标([])、调用(())和成员访问箭头(->)运算符必须是成员函数;
        ② 复合赋值运算符一般来说应该是成员,但非必须,这一点与赋值运算符略有不同;
        ③ 改变对象状态的运算符或者与给定类型密切相关的运算符,如递增、递减和解引用运算符,通常应该是成员;
        ④ 具有对称性的运算符可能转换任意一端的运算对象,例如算数、相等性、关系和位运算符等,因此它们通常应该是普通的非成员函数。
  7. 通常,输出运算符应该主要负责打印对象的内容而非控制格式,输出运算符不应该打印换行符。
  8. 与 iostream 标准库兼容的输入输出运算符必须是普通的非成员函数,而不能是类的成员函数。 IO 运算符通常需要读写类的非公有数据成员,因此 IO 运算符一般被声明为友元。
  9. 输入运算符必须处理输入可能失败的情况,而输出运算符不需要。
  10. 在执行输入运算符时可能发生下列错误:
        ① 当流含有错误类型的数据时读取操作可能失败;
        ② 当读取操作打到文件末尾或者遇到输入流的其他错误时也会失败。
  11. 当读取操作发生错误时,输入运算符应该负责从错误中恢复。
  12. 如果类同时定义了算术运算符和相关的复合赋值运算符,则通常情况下应该使用复合赋值运算符来实现算术运算符。
  13. 相等运算符的设计准则:
        ① 如果一个类含有判断两个对象是否相等的操作,则它显示应该把函数定义成 operator== 而非一个普通的命名函数;
        ② 如果类定义了 operator== ,则该运算符应该能判断一组给定的对象中是否含有重复数据;
        ③ 通常情况下,相等运算符应该具有传递性;
        ④ 相等运算符和不相等运算符中的一个应该把工作委托给另一个。
  14. 通常情况下关系运算符应该:
        ① 定义顺序关系,令其与关联容器中对关键字的要求一致;
        ② 如果类同时也含有 == 运算符的话,则定义一种关系令其与 == 保持一致。特别是,如果两个对象是 != 的,那么一个对象应该 < 另一个对象。
  15. 我们可以重载赋值运算符。不论形参的类型是什么,赋值运算符都必须定义为成员函数。
  16. 复合赋值运算符不非得是类的成员,不过我们还是倾向于把包括复合赋值运算符在内的所有赋值运算符都定义在类的内部。为了与内置类型的复合赋值保持一致,类中的复合赋值运算符也要返回其左侧运算对象的引用。
  17. 如果一个类包含下标运算符,则它通常会定义两个版本:一个返回普通引用,另一个是类的常量成员并且返回常量引用。
  18. 定义递增和递减运算符的类应该同时定义前置版本和后置版本。因为它们改变的正好是所操作对象的状态,所以这些运算符通常应该被定义成类的成员。
  19. 为了与内置版本保持一致,前置运算符应该返回递增或递减后对象的引用,而后置运算符应该返回对象的原值而非引用。
  20. 函数调用运算符必须是成员函数。一个类可以定义多个不同版本的调用运算符,相互之间应该在参数数量或类型上有所区别。
  21. C++ 语言中有几种可调用的对象:函数、函数指针、 lambda 表达式、 bind 创建的对象以及重载了函数调用运算符的类。
  22. 对于类来说,定义向 bool 的类型转换还是比较普遍的现象。
  23. 如果表达式被用作条件,则编译器会将显示的类型转换隐式地执行。
  24. 向 bool 的类型转换通常用在条件部分,因此 operator bool 一般定义成 explicit 的。
  25. 通常情况下,不要为类定义相同的类型转换,也不要再类中定义两个及两个以上转换源或转换目标是算数类型的转换。
  26. 如果调用重载函数时我们需要使用构造函数或者强制类型转换来改变实参的类型,则这通常意味着程序的设计存在不足。
  27. 如果我们对同一个类既提供了转换目标是算数类型的类型转换,也提供了重载的运算符,则将会遇到重载运算符与内置运算符的二义性问题。
0 0
原创粉丝点击