假设有一个有理数类Rational,有一个计算有理数乘法的成员函数operator*,示例如下:

 #include <iostream>

 class Rational
{
public:
Rational(int numerator = , int denominator = )
{
n = numerator; // 分子
d = denominator; // 分母
}
int numerator() const
{
return n;
}
int denominator() const
{
return d;
}
const Rational operator*(const Rational& rhs) const
{
return Rational(this->n * rhs.n, this->d * rhs.d);
} private:
int n;
int d;
}; int main()
{
Rational oneEight(, );
Rational oneHalf(, );
Rational result1 = oneEight * oneHalf; // 同类型运算
34 Rational result2 = oneHalf * 3; // 混合运算1
35 Rational result3 = 3 * oneHalf; // 混合运算2  
std::cout << result1.numerator() << "/" << result1.denominator() << std::endl;
std::cout << result2.numerator() << "/" << result2.denominator() << std::endl;
std::cout << result3.numerator() << "/" << result3.denominator() << std::endl; return ;
}


如上可见,该乘法运算对于执行同类型运算没有任何问题,为什么对于执行混合运算却有时可以,有时又不可以呢?其实,我们知道执行oneHalf * 3时,编译器调用oneHalf的成员函数,然后对于3执行隐式类型转换(调用Rational的构造函数完成的),转换为Rational后执行乘法运算,因此没出现错误;但是对于3 * oneHalf而言就不同了,因为3并没有相应的成员函数,因此,编译器将试图寻找non-member operator*:result = operator*(2, oneHalf),但是很遗憾,你没有提供这样的函数,因此发出错误。因此结论是:像这种需要发生类型转换才能继续工作的函数,你必须提供一个non-member函数来完成工作,示例如下:

 const Rational operator*(const Rational& lhs, const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(), lhs.denominator() * rhs.denominator());
}


这样的话上述的两种混合调用方式都可以通过了。因此请记住如下结论:

当你设计的某个函数的所有参数(包含this指针所指的那个隐含参数)都可能需要发生类型转换时,那么这个函数必须是non-member函数。

条款24:若所有的函数参数可能都需要发生类型转换才能使用,请采用non-member函数的更多相关文章

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

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

  2. 深入理解javascript函数参数与闭包(一)

    在看此文章,希望先阅读关于函数基础内容 函数定义与函数作用域 的章节,因为这篇文章或多或少会涉及函数基础的内容,而基础内容,我放在函数定义函数作用域 章节. 本文直接赘述函数参数与闭包,若涉及相关知识 ...

  3. C++数组(指针)作为函数参数

    本文的学习内容参考:http://blog.csdn.net/wwdlk/article/details/6322843 1.当用数组名作为函数参数时,函数的实参和形参都应为数组名(或者指针): Ex ...

  4. php的函数参数按照从左到右来赋值

    PHP 中自定义函数参数赋默认值 2012-07-07 13:23:00|  分类: php自定义函数,默|举报|字号 订阅     下载LOFTER我的照片书  |     php自定义函数接受参数 ...

  5. Day8 函数指针做函数参数

    课堂笔记 课程回顾         多态 virtual关键字 纯虚函数 virtual func() = 0;         提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...

  6. Java获取函数参数名称

    原理 编译之后的class文件默认是不带有参数名称信息的,使用 IDE 时,反编译jar包得到的源代码函数参数名称是 arg0,arg1......这种形式,这是因为编译 jar 包的时候没有把符号表 ...

  7. python 函数参数的传递(参数带星号的说明) 元组传递 字典传递

    python中函数参数的传递是通过赋值来传递的.函数参数的使用又有俩个方面值得注意:1.函数参数是如何定义的 2.在调用函数的过程中参数是如何被解析 先看第一个问题,在python中函数参数的定义主要 ...

  8. pyhton 函数参数,递归函数,高阶函数(一点点笔记)

    '''def test(x,y): print(x) print(y)test(2,y=3)def test(*args):#参数可以是不确定的多个数,接受N个位置参数,转换成元组形式 print(a ...

  9. ES6函数参数默认值作用域的模拟原理实现与个人的一些推测

    一.函数参数默认值中模糊的独立作用域 我在ES6入门学习函数拓展这一篇博客中有记录,当函数的参数使用默认值时,参数会在初始化过程中产生一个独立的作用域,初始化完成作用域会消失:如果不使用参数默认值,不 ...

随机推荐

  1. wcscpy wcscpy_s strcpy strcpy_s的区别

    原型声明:extern char *strcpy(char *dest,const char *src); 头文件:string.h 功能:把从src地址开始且含有NULL结束符的字符串赋值到以des ...

  2. ionic phonegap translate language demo

    中英文转换,经常用到:而ionic  则是通过angular js 来实现: 用到了 http://www.ng-newsletter.com/posts/angular-translate.html ...

  3. WWF3控制流程类型活动<第二篇>

    一.顺序工作流 顺序活动是WWF工作流中最基本.最简单的容器类型的活动.顺序活动可以作为很多其他活动的分支. 代码: private void CodeExecute1(object sender, ...

  4. Qt Meta Object System-元对象系统

    研一的时候开始使用Qt,感觉用Qt开发图形界面比MFC的一套框架来方便的多.后来由于项目的需要,也没有再接触Qt了.现在要重新拾起来,于是要从基础学起. Now,开始学习Qt事件处理机制. 元对象系统 ...

  5. Android IOS WebRTC 音视频开发总结(八)-- ios上移植webRTCDemo

    这篇文章主要介绍ios webrtcdemo的实现及相关注意事项,转载请说明出处(博客园RTC.Blacker) 前面很多人问webrtc android下有webrtcdemo,ios上怎么找不到, ...

  6. 新手浅谈Task异步编程和Thread多线程编程

    初学Task的时候上网搜索,看到很多文章的标题都是task取代thread等等相关,我也一直以为task和thread是一类,其实task是.net4.0提出的异步编程,在之前.net1.0有dele ...

  7. [原]hdu2602 Bone Collector (01背包)

    本文出自:http://blog.csdn.net/svitter 题意:典型到不能再典型的01背包.给了我一遍AC的快感. //=================================== ...

  8. Js/Ajax中发送HttpPost请求调用WebService

    1) WebService中的方法 [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(Confo ...

  9. Objective-C中的self和super

    1.有过面向对象的人知道,self相当于this,super相当于调用父类的方法 2.self是类的隐藏的参数,指向当前调用方法的类,另一个隐藏参数是_cmd,代表当前类方法的selector. su ...

  10. 在peopletools里面测试文件上传

    Using the PeopleTools Test Utilities Page Select selectPeopleTools, then selectUtilities, then selec ...