引言

假设我们有这样的类:

 class A{
public:
A(int num = , int den = ) {};
int num() const;
int den() const;
const A operator* (const A& rhs) const;
};

在做乘法时,我们可以采用以下的操作:

     A a0(, );
A a1(, ); A match = a0 * a1; // 同类型相乘
match = match * a0; // 同类型相乘

上述操作是完全木有问题的,那么如果我们想实现跨类型相乘应该怎么做呢?

于是我们开始尝试这样来操作

     match = a0 * ;       // OK        match = a0.operator * 2
match = * a0; // Error match = 2.operator * a0

是的,a0是一个包涵了operator*函数的class的对象,所以编译调用此函数。然而2却没有相应的class,也就没有相对应的operator*函数。

而上面成功的操作中,实际上调用了隐式转换函数,在编译器看来,实际执行的操作为:

 const A temp();     // 基于2建立一个临时对象
match = a0 * temp; // 等同于a0.operator * (temp);

这时如果我们将A的构造函数换成explicit函数,那么上述任何一种情况都不能进行隐式转换,也就没有任何一个语句可以编译通过。

让我们再深挖一些,为什么 match = 2 * a0;就不能通过隐式转换来完成呢?

答案是:只有当参数被列于参数列内,这个参数才是隐式转换的合格参与者。地位相当于”被调用的成员函数所属的那个对象“--即this对象的隐喻参数,不会是合格的参与者。这就是为什么第一次编译通过,而第二次编译不通过的原因:第一次调用伴随着一个放在参数列内的参数,而第二次调用则否。

一、使用non-member函数

如果我们一定要实现跨类型相乘,可以使用non-member来解决。

 class A{
public:
A(int num = , int den = ) {};
int num() const;
int den() const;
};
const A operator* (const A& lhs, const A& rhs) {
return A(lhs.num() * rhs.num(),
lhs.den() * rhs.den());
}

在这种情况下,下面的任意一种情况都可以实现:

     A a0(, );
A a1(, ); A match = a0 * a1;
match = match * a0; match = a0 * ;
match = * a0;

◆总结

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

[Effective C++ --024]若所有参数皆需类型转换,请为此采用non-member函数的更多相关文章

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

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

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

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

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

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

  4. 【24】若所有参数皆需类型转换,请为此采用non-members函数

    1.令class支持隐式类型转换,往往是个糟糕的主意.但有些情况是合理的,比如数值类型.考虑,有理数Rational有分子,分母两个字段,缺省参数值为0,1.Ration a = 2;我们期望构造一个 ...

  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. 对setTimeout()第一个参数是字串的深入理解以及eval函数的理解

    <script language="javascript" type="text/javascript"> var a=1; setTimeout( ...

  9. Effective C++ 之 Item 6 : 若不想使用编译器自动生成的函数,就该明确拒绝

    Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 6 ...

随机推荐

  1. I.MX6 wm8962 0-001a: DC servo timed out

    /******************************************************************************* * I.MX6 wm8962 0-00 ...

  2. 剑指Offer:第一个只出现一次的字符

    题目:在字符串中找出第一个只出现一次的字符.如输入"abaccdeff",这输出'b' // 第一个只出现一次的字符 #include <stdio.h> char f ...

  3. .NET 4.0中的泛型协变和逆变

    随Visual Studio 2010 CTP亮相的C#4和VB10,虽然在支持语言新特性方面走了相当不一样的两条路:C#着重增加后期绑定和与动态语言相容的若干特性,VB10着重简化语言和提高抽象能力 ...

  4. HDU 5534 Partial Tree 完全背包

    一棵树一共有2*(n-1)度,现在的任务就是将这些度分配到n个节点,使这n个节点的权值和最大. 思路:因为这是一棵树,所以每个节点的度数都是大于1的,所以事先给每个节点分配一度,答案 ans=f[1] ...

  5. 【译】 AWK教程指南 9读取命令行上的参数

    大部分的应用程序都允许使用者在命令之后增加一些选择性的参数.执行awk时这些参数大部分用于指定数据文件文件名,有时希望在程序中能从命令行上得到一些其它用途的数据.本小节中将叙述如何在awk程序中取用这 ...

  6. suds 在python3.x上的安装并访问webservice

    类库安装 直接使用命令行:pip install suds 报错:Traceback (most recent call last):    File "setup.py", li ...

  7. bzoj 3131 [Sdoi2013]淘金(数位DP+优先队列)

    Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块.    一阵风吹 ...

  8. 《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇05:二段跳》

    5.二段跳 二段跳概述: 基本跑酷游戏的框架搭建完毕,开发者会根据开发的游戏特性,增设一些额外功能,使游戏具有可玩性性和画面感.下面我们以角色的二段跳为例,来了解在跑酷游戏中增设其它功能的流程.二段跳 ...

  9. Codeforces Round #105 (Div. 2) ABCDE

    A. Insomnia cure 哎 只能说英语太差,一眼题我看了三分钟. 题意:给5个数k, l, m, n 和 d,求1~d中能被k, l, m, n 至少一个整除的数的个数. 题解:…… 代码: ...

  10. elecworks 报表----按线类型的电线清单

    按线类型的电线清单中:列Wire number指的是线标注,不是电位标注 section:截面积