zoukankan      html  css  js  c++  java
  • 【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。

  • 相关阅读:
    《跑跑跑》(五)——添加障碍物,Tiled障碍层的使用
    Cocos2d-JS 自定义loading界面
    Oracle本地,远程,分布式登录
    JUnit测试工具在项目中的用法
    js事件之神奇的onclick
    js常见事件
    JS & DOM 对象
    jquery方法的参数解读
    JDBC和DBUtils区别(查询时jdbc只能返回ResultSet需要po转vo,dbutils返回的BeanListHandler与BeanHandler对应集合与对象)
    AJAX技术的核心
  • 原文地址:https://www.cnblogs.com/nzbbody/p/3531585.html
Copyright © 2011-2022 走看看