引言

假设我们有这样的类:

 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. [.NET MVC进阶系列0x] EF Code First 数据迁徙(Migrations)

    [因] Entity Framework中使用Code First模式进行开发时,数据库是基于Models中的类自动生成的(生成时间:第一次运行MVC项目时), 每次更改Models中类结构,重新编译 ...

  2. 新功能:Azure Traffic Manager 嵌套配置文件

    Jonathan Tuliani  Azure 网络 - DNS 和 Traffic Manager 项目经理 我们很高兴地宣布,Azure Traffic Manager 支持 Traffic Ma ...

  3. Entity Framework4.0 (七) EF4的存储过程

    前面了解了EF4的CRUD的操作,你会发现EF4使用起来比较简单的.呵呵,之前我们使用数据库的时候,有时会使用存储过程代替在代码中直接使用SQL语句. 使用存储过程的好处: 提高效率:因为存储过程是经 ...

  4. LINQ,EF联合查询join

    public object GetListAdmin() { //return db_C56.Admins //   .Where(a => a.Status != "D") ...

  5. 静态Web开发 DOM

    四章 Dom 1节dom中的顶级对象 dom(文档对象模型)js最终是要操作html页面,让html变成DHtml,而操作Html页面就要用到DOMDOM可以吧Html页面模拟成一个对象,如果js只是 ...

  6. Java面试宝典2013版(超长版)

    一. Java基础部分......................................................................................... ...

  7. UVAlive3662 Another Minimum Spanning Tree 莫队算法

    就是莫队的模板题 /* Memory: 0 KB Time: 1663 MS Language: C++11 4.8.2 Result: Accepted */ #include<cstdio& ...

  8. vs2010中的快捷键

    1.Ctrl+TAB  vs中各个页进行切换. 2.shift+alt+F10 用于帮助绑定选定项的选项.就用于写了一个类(Regex),需要导入其所在命名空间时(using System.Text. ...

  9. HIbernate学习笔记(五) 关系映射之一对多与多对一

    三.       多对一 –单向 场景:用户和组:从用户角度来,多个用户属于一个组(多对一 关联) 使用hibernate开发的思路:先建立对象模型(领域模型),把实体抽取出来. 目前两个实体:用户和 ...

  10. keil中 code、data、idata的区别

    存储器类型 本C51编译器支持8051及其派生类型的结构能够访问8051的所有存储器空间具有下表列出的存储器类型的变量都可以被分配到某个特定的存储器空间.存储器类型 描述code 程序空间64 Kby ...