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。

【24】若所有参数皆需类型转换,请为此采用non-members函数的更多相关文章

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

    若所有的参数皆需要类型转换--请为此采用non-member函数 经常使用C++的程序猿(希望更多的程序媛),一般不会同意让classes支持类型转换,至于为什么,请看后续的博客.假如我们设计一个表示 ...

  2. Effective C++ -----条款24:若所有参数皆需类型转换,请为此采用non-member函数

    如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member.

  3. [Effective C++ --024]若所有参数皆需类型转换,请为此采用non-member函数

    引言 假设我们有这样的类: class A{ public: A(, ) {}; int num() const; int den() const; const A operator* (const ...

  4. [EffectiveC++]item24:若所有参数皆需类型转换,请为此采用non-member函数

    Declare non-member functions when type conversions should apply to all parameters. 104页 只有当参数被列于参数列( ...

  5. 读书笔记_Effective_C++_条款二十四: 若所有参数皆需类型转换,请为此采用non-member函数

    class A { private: int a; public: A(int x) :a(x){} A operator*(const A& x) { return A(a*x.a); } ...

  6. 条款24:若所有参数皆需要类型转换,请为此采用non-member函数(Declare non-member functions when type conversions should apply to all parameters)

    NOTE: 1.如果你需要为某个函数的所有参数(包括this指针所指的那个隐喻参数)进行类型转换,那么这个函数必须是个non-member.

  7. 条款24:如果所有的参数都需要类型转换,那么请为此采用non-member函数

    首先还是下面这个class; class Rational{ public: Rational(, ); int numurator() const; int denominator() const; ...

  8. 微信h5支付出现“商家参数格式有误,请联系商家解决”

    在浏览器进行微信h5支付时出现:

  9. js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快、简单 post:安全,量大,不缓存)(服务器同步和异步区别:同步:等待服务器响应当中浏览器不能做别的事情)(ajax和jquery一起用的)

    js中ajax连接服务器open函数的另外两个默认参数get请求和默认异步(open的post方式send函数带参数)(post请求和get请求区别:get:快.简单 post:安全,量大,不缓存)( ...

随机推荐

  1. pb 插入控件是出问题

    http://m.blog.csdn.net/blog/jqz1225/34417493 是的http://blog.163.com/wufeng_1213/blog/static/167783313 ...

  2. Android开发之R文件丢失

    在进行android开发的过程中,不知道怎么回事,代码中出现R代码有红色波浪线了,于是进行了clean,结果还是有红色波浪线,然后就重启了eclipse,重启以后还是这个样子,随后发现工程的R文件丢失 ...

  3. js构造函数式编程

    1.函数式编程 //创建和初始化地图函数: function initMap(){ createMap();//创建地图 setMapEvent();//设置地图事件 addMapControl(); ...

  4. What is Cross Linux From Scratch?

    /**************************************************************************** * What is Cross Linux ...

  5. Spring 教程(一)

    一.Spring是什么 通常说的Spring其实指的是Spring Framework,它是Spring下的一个子项目,Spring围绕Spring Framework这个核心项目开发了大量其他项目, ...

  6. 解析activity之间数据传递方法的详解

    转自:http://www.jb51.net/article/37227.htm 本篇文章是对activity之间数据传递的方法进行了详细的分析介绍,需要的朋友参考下     1  基于消息的通信机制 ...

  7. HDU 5675 ztr loves math

    ztr loves math Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)To ...

  8. 《深入Java虚拟机学习笔记》- 第6章 class文件

    一.class文件内容 Java class文件是对Java程序二进制文件格式的精确定义.每一个Java class文件都对一个Java类或者Java接口作出了全面描述.一个class文件只 能包含一 ...

  9. OD使用经验【转载】

    文章整理发布:黑客风云  1.我的os是winXP,无法使用trw2000,而softice装了多次均未成功,还蓝屏死机多次.郁闷. 2.友好的gui界面,不像softice.可以边干活边听歌,不像s ...

  10. 25、BroadCastRecevier

    BroadCastRecevier 有两种注册方式 1. 清单文件里注册: 一旦应用程序被部署到手机, 广播接受者就会生效 2. 代码里面注册: 一旦代码所在的进程被杀死了, 广播接受者就失效了. 广 ...