【24】若所有参数皆需类型转换,请为此采用non-members函数
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。
最新文章
- 采集数据和memchche的存储使用,分页展示
- 读卡器的Win32 Dll调用
- AJax中post与get请求注意事项
- netstat 查看TCP状态值
- light oj 1138
- 二、FreeMarker 模版开发指南 第二章 数值和类型
- 行为树实现AI逻辑
- iOS开发 UITableView之cell
- 从[java.lang.OutOfMemoryError: Java heap space]恢复
- 西瓜书概念整理(chapter 1-2)
- dense prediction问题
- Keras和tensorflow的区别
- Ajax增删改查-----------查
- Jmeter(三十二)_搭建本地接口自动化环境
- 一步步实现windows版ijkplayer系列文章之六——SDL2源码分析之OpenGL ES在windows上的渲染过程
- Linux shell脚本读取用户输入的参数
- HDU 1717 小数化分数2(最大公约数)
- Java接口和抽象类理解(New)
- codeforces 730 j.bottles
- 【JSP EL】使用EL表达式比较 动态选中 select中的option
热门文章
- OM Price Lists
- Hadoop伪分布模式配置部署
- innodb master thread 工作原理
- storm - 使用过程中的一点思考
- UVa 1152 (中途相遇法) 4 Values whose Sum is 0
- VC++6.0环境下调试c语言代码的方法和步骤_附图
- js判断checkbox是否已选
- spinner 设置文本框中的字体颜色
- error MSB3027: Could not copy ";xxx.dll"; to ";xxx.dll";. Exceeded retry count of 10. Failed.
- 那些年一起踩过的坑 — Date类型序列化的问题