1、令class支持隐式类型转换,往往是个糟糕的主意。但有些情况是合理的,比如数值类型。考虑,有理数Rational有分子,分母两个字段,缺省参数值为0,1。Ration a = 2;我们期望构造一个分子为2,分母为1的有理数,这是非常合理和自然的。因此,Rational的构造方法为Ration(int numerator =0, int denominator =1);不添加explicit。

2、考虑Rational 有个成员方法 operator*,如下:

  const Ration operator*(const Rational& rhs) const;

  Rational a (1,2);

  Rational result;

  result = a*2; // OK

  result = 2*a; // Error

  为什么?

  对于a*2,2会隐式转化为Rational,而对于2*a,2不会隐式转化为Rational。这种情况下,编译器尝试查找non-member方法的调用,即operator(2,a); 在当前名称空间或者全局global作用域查找不到,报错。

3、分析下,为什么对于2*a,2不会隐式转化为Rational。

  调用方法的时候,如果没有完全匹配的方法,编译器尝试进行一次隐式类型转换,使之与方法匹配成功。可认为编译器做了一次适配的过程,实参与形参类型不一致,把实参转化为形参的类型,从而匹配成功。

  对于a*2,2对应形参,而对于2*a,2对应this指针常量。不能隐式转化为this指针。再接着思考,为什么不能转化为this指针?

  假如可以隐式转化为this指针,那么有成千上万的类(没有声明explicit构造方法),当调用2*a的时候,编译器必须遍历每一个类,查看这个类中是否有* Rational的成员方法,显然不可能。

4、另外,还有一点,隐式类型转换只能进行一次,不能进行多次。也就是说,2 -> XXX -> Person是不可行的。思考下,为什么?

  假如隐式类型转换允许多次,就意味着,从2 到Person的转换过程,编译器必须查找出所有可能的转换路径,这显然不切实际。即使,找到了所有的转换路径,那么,存在多个转换路径,到底使用哪一个呢?

5、怎么解决上面的问题呢?  即2*a。

  既然不能隐式转换为this指针,那么就是用non-member方法。这样的话,无论对于哪个形参需要隐式类型转化,都可以。编译器从当前名称空间或者全局作用域,查找operator*(Rational ,Rational),这种形式的方法毕竟很有限。

6、定义的non-member方法,是否需要声明为Rational的friend方法?

  根据经验,尽量避免使用friend,为啥?因为friend破坏了封装。因此,如果不需要访问Rational的private成员,就不要声明为friend。

最新文章

  1. 采集数据和memchche的存储使用,分页展示
  2. 读卡器的Win32 Dll调用
  3. AJax中post与get请求注意事项
  4. netstat 查看TCP状态值
  5. light oj 1138
  6. 二、FreeMarker 模版开发指南 第二章 数值和类型
  7. 行为树实现AI逻辑
  8. iOS开发 UITableView之cell
  9. 从[java.lang.OutOfMemoryError: Java heap space]恢复
  10. 西瓜书概念整理(chapter 1-2)
  11. dense prediction问题
  12. Keras和tensorflow的区别
  13. Ajax增删改查-----------查
  14. Jmeter(三十二)_搭建本地接口自动化环境
  15. 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程
  16. Linux shell脚本读取用户输入的参数
  17. HDU 1717 小数化分数2(最大公约数)
  18. Java接口和抽象类理解(New)
  19. codeforces 730 j.bottles
  20. 【JSP EL】使用EL表达式比较 动态选中 select中的option

热门文章

  1. OM Price Lists
  2. Hadoop伪分布模式配置部署
  3. innodb master thread 工作原理
  4. storm - 使用过程中的一点思考
  5. UVa 1152 (中途相遇法) 4 Values whose Sum is 0
  6. VC++6.0环境下调试c语言代码的方法和步骤_附图
  7. js判断checkbox是否已选
  8. spinner 设置文本框中的字体颜色
  9. error MSB3027: Could not copy "xxx.dll" to "xxx.dll". Exceeded retry count of 10. Failed.
  10. 那些年一起踩过的坑 — Date类型序列化的问题