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. 深入理解Java虚拟机 - 垃圾收集概述

    首先需要澄清的是,垃圾收集(GC)的历史远比Java要久远,当我们意识到手动管理内存所带来的麻烦时,懒惰的天性推动先驱们寻找更为简单.易用.关键是傻瓜式的内存管理技术.GC技术起源于1960年诞生于M ...

  2. windows官方多语言方案

    编写 Win32 多语言用户界面应用程序 Windows 2000 针对全球市场制定了新的增强支持标准,提供了许多国际化功能,例如完全支持 Unicode.预设支持数百种语言以及用于从右向左语言的镜像 ...

  3. 实现类似QQ的即时通信程序(十一)

    此为网络编程的一个系列,后续会把内容补上....

  4. 【MooTools】

    MooTools a compact javascript frameworkhttp://mootools.net/docs/core 30天学会 MooTools 教学(1): 认识MooTool ...

  5. 在 ASP.NET MVC4 中使用 NInject

    Ninject是一个快如闪电.超轻量级的基于.Net平台的依赖注入框架.它能够帮助你把应用程序分离成一个个松耦合.高内聚的模块,然后用一种灵活的方式组装起来.通过使用Ninject配套你的软件架构,那 ...

  6. Entity Framework中查看生成的SQL语句

    Entity Framework 4.0 中是这样的,高版本的跟这个有些差异,不太一样,貌似已经到7了 using (Entities entities = new Entities()) { var ...

  7. SqlSugar轻量ORM

      蓝灯软件数据股份有限公司项目,代码开源. SqlSugar是一款轻量级的MSSQL ORM ,除了具有媲美ADO的性能外还具有和EF相似简单易用的语法. 学习列表 0.功能更新 1.SqlSuga ...

  8. 数列极限---和Gauss(取整)函数有关

  9. 【JMeter】JMeter完成一个MySql压力测试

    jmeter也可以用来做数据库的压力测试,并且兼容各种数据库类型,只需要更改对应的数据库驱动类和url.以下为整理到的数据库驱动类对应url.并且给出一个mysql数据库select的简单应用.如下: ...

  10. HDU 1074 Doing Homework 状压DP

    由于数据量较小,直接二进制模拟全排列过程,进行DP,思路由kuangbin blog得到,膜拜斌神 #include<iostream> #include<cstdio> #i ...