zoukankan      html  css  js  c++  java
  • 若所有的参数皆需要类型转换——请为此采用non-member函数

    若所有的参数皆需要类型转换——请为此采用non-member函数#

    经常使用C++的程序猿(希望更多的程序媛),一般不会同意让classes支持类型转换,至于为什么,请看后续的博客。假如我们设计一个表示有理数的class,允许”整数隐式转换为有理数似乎很合理“。首先来一个简单的实现。

    class Rational
    {
    public:
        Rational(int numerator = 0,int denominator = 1;    //允许int-to-Rational隐式转换 
        int numerator()const;
        int denominator()const;
        const Rational operator*(const Rational& rhs)const;    //有理数的乘法
        ...
    };
    

    有理数,我们很自然地为他实现了乘法的运算。我们可以轻松地实现两个有理数相乘,但是,假如我们想要进行混合运算呢?在下面的例子中,2在第一个参数与第二个参数的位置进行隐私类型转换。

    
    Rational half(1,2);
    half = half * 2;    //1. 通过编译  
    half = 2 *half;     //2. 无法通过编译
    

    为什么会这样呢?对于1,编译器解释如下,所以很正常地通过了编译。

    operator*(Rational& this,Rational& rhs);    //函数的定义部分     
                                                //第一个参数是没办法改变的,一定是被乘数  
    half.operator(Rational(2));                 //函数的调用部分,2被隐式转换为了有理数
    //与下面的代码一致
    const Rational temp(2);
    result = half * temp;
    

    编译器拿到2的时候,知道operator*()需要一个Rational,也知道只要调用Rational的构造函数就能够变出一个适当的Rational,所以,它就做了。
    结果就是上面的例子。当然,必须存在non-explicit编译器才会这么做。

    而对于2中的代码呢,编译器首先试着如下解释

    2.operator*(half);
    

    很明显,2.operator()是不存在的东西,所以,编译器会尝试着寻找一个non-memb operator(),但结果是:没有找到。所以只能返回一个错误。

    很明显,上面对于同一个操作符,却有了两种截然不同的结果,你十分抵触。然后你就会义愤填膺地把构造函数修改为explicit。结果是:两者一致了,都不支持混合运算。但是,我们的目标不仅仅在于一致性,我们还希望它支持混合运算。那么,请拿出我们的利器:non-member函数。我们暂时允许编译器执行隐式类型转换。

    class Rational
    {
        ...
    };
    const Rational operator*(const Rational& lhs,const Rational& rhs);
    Rational half(1,2);
    half = half * 2;    //通过编译
    half = 2 * half;    //通过编译
    

    真的是峰回路转疑无路,千辛万苦终于找到可行之道。对于上面的代码,编译器会对每个2都转换为Rational(2)。当你完成了一天的工作后,最后一个要操心的问题是:是否需要一个non-member friend函数?假如否定的,member的对立面不是non-member friend函数。使用了friend,意味着公开自己的所有隐私。这种严重破坏自身隐私的可不是好事,可以参考以下的博客太过亲密往往不好——用NON-MEMBER,NON-FRIEND替换MEMBER函数还有为了更好更方便地活着——爱上PRIVATE.

    总结一下

    1. 假如你需要为某个函数的所有参数都进行类型转化的时候,这个函数必须是non-member。

    2. member的对立面不是non-member friend,请慎用friend。

  • 相关阅读:
    css3在不同型号手机浏览器上的兼容一览表
    android 常见分辨率(mdpi、hdpi 、xhdpi、xxhdpi )及屏幕适配注意事项
    web app iphone4 iphone5 iphone6 iphone6 Plus响应式布局 适配代码
    用sql查询当天,一周,一个月的数据
    VS2010 生成Xml格式的注释文档
    VS XML注释
    css3 box-sizing属性
    CSS技巧(一):清除浮动
    使用Windows Server 2003搭建一个asp+access网站
    如何在Windows Server 2003搭建Windows+iis+asp+access环境
  • 原文地址:https://www.cnblogs.com/suimeng/p/4887195.html
Copyright © 2011-2022 走看看