第14章 操作重载与类型转换
但是如果对于一个运算符比如+号,既有重载的成员函数,又有重载的非成员函数,那么此时如果直接使用+号,那么就会出现错误. 因为编译器不知道要调用那个运算符.
2. 逗号,运算符 逻辑与&&运算符 逻辑或||运算符不建议重载.
因为上述3种运算符本身是有求值顺序和短路求值特性(&&和||有短路求值特性)的. 但是重载后的运算符本质上是一次函数调用, 所以求值顺序和短路求值特性都会消失.
注意上面第一个a&&(v--)打印的是1而不是0. 就算你用()括住v--, v—这个表达式的返回值依然是v的原始值.
3. 赋值(=), 下标([]), 调用( () ), 成员访问箭头(->)的重载运算符函数必须定义为类的成员函数(否则编译不通过).
4. 重载的运算符的不同类型参数的顺序不可改变.
因为重载了A+int的运算符,所以a+v正确但是v+a是错的.
但是下面的”111”和s却可以任意调换顺序?
因为定义了的是非成员函数operator+(string,string),而不是operator+(const char*, string) 所以字符串常量会自动隐式转化为string对象.
5. 重载输入输出运算符>>和<<.
首先两个运算符的os is 参数和返回值必须是非const的引用. 因为流对象不可拷贝且会改变状态.
其次对于输入运算符>>,类的对象必须是非const引用. 对于输出运算符<<,类的对象建议为const 引用.
6. 相等运算符==与不等运算符!=
一般一个类定义了==运算符,那么一般也要定义一个不等!=运算符.
且!=运算符只是调用==运算符来工作, 即只有一个运算符真正负责比较工作.
7. 可以给一个类定义多个重载的运算符。
8. 重载下标运算符[]
重载下标运算符[]首先应返回引用,其次一般定义const版本和非const版本两个重载函数。
因为b是常量,所以我们不能给b[2]赋值的。
9. 重载递增++递减--运算符。
首先,每种运算符建议重载前置和后置两个版本。
其次,前置版本返回引用,后置版本返回值。
10. 重载*解引用和->成员访问运算符。
注意:
*解引用返回对象的引用,->成员访问运算符返回成员的地址。
->成员访问运算符获取成员这一事实永不变.
11. 类类型转换
类类型转换由:隐式转换构造函数(单参数构造函数)和类型转换运算符共同定义。
隐式转换构造函数: 别的类型转换为当前类的类型。
类型转换运算符: 当前类对象转换为其他类型。
类型转换运算符无显示返回类型,无形参,必须定义成类的成员函数。
12. 有二义性的类型转换
情况一:假设现在要把B类型对象转换为A类型对象。且如果A中有参数为B对象的构造函数且B中有目标对象为A的类型转换运算符,那么从B->A时,既可以调用A的转换构造函数,又可以调用B的转换运算符,产生二义性。
情况二:如果类A存在与多个内置算术类型之间的转换,那么要小心。
情况三:假设func(Dd)和func(Cc)是两个重载的函数。且D和C类对象都可以用int转换得来,那么func(10)调用将产生二义性。
结论:除了显式的(explicit)向bool类型的转换之外,应尽量避免定义类型转换运算符和非显式的转换构造函数。
原文地址:http://blog.csdn.net/u013480600/article/details/44170999