`
lovnet
  • 浏览: 6672122 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

C++与C#对比学习:函数(四)重载函数匹配

 
阅读更多

重载函数匹配与美女挑老公的对比

我们知道重载函数中可以形参个数相同,但类型不同.而C++中双允许做比较灵活的隐式类型转换.所以调用函数时怎么精确的匹配到要想的函数就是一个问题.

此时一般分三个步骤去匹配

(1)先把所有重载函数找出来.把形参个数相同的先选出来.形参个数不同的就直接剔除掉.这相当于是海选,比如人家美女找老公,先看第一感觉,如果第一感觉不好.你进入海选的机会都没有.

(2).然后从参数相同的候选的函数中去匹配形参.如果找到完全吻合的某一个就大功告成了.就跟美女找到有钱又帅又有感觉的自然就非你不嫁了啊.但理想是美好的,现实是残酷的,有时没这么完美的事.可能是帅得一踏糊涂,但也穷得一踏糊涂.或者有钱多得自己也数不清了,但丑得都不像人类了.

(3)找不到完全匹配的先做隐式类型转换.如果匹配到唯一的一个的话就也OK.这就跟美女可能只有一个有钱的人,或者一个长得帅的哥们有的挑.那就不用选了嘛.

(4)如果进行类型转换后有几个匹配咋整?要按照一个规则进行判断,哪个匹配最优就选哪个.这就跟美女在几个帅的和有钱的中,最后发现一个有很钱,但得还勉强能被当作人,不会被当作野人或大猩猩啥的.于是也OK

(5)在(4)中如果按照规则去匹配,结果还没能得到唯一的选择,而是得到两个或多个符合条件的.这是计算机就傻眼了.直接报错.不过人可聪明点.美女可能犹豫不决时就会征求闺蜜们的意见.或者实在不行抓阄算了.可不能犹豫不决让煮熟的鸭子飞了啊.这是聪明女人的做法,但也有胸大无脑的女的啊.犹豫来犹豫去,结果那些男的都被其他女妖精们拐跑了.到时年已年容貌已不再就只能屈尊嫁给某个以前自己都看不上眼的男的了啊.日后心里不平衡可能还偶尔给那男的戴戴绿帽啥的

用C#来举个例子

假如有如下5个重载函数

void Fun(string name){ } (1)

void Fun(int num) { } (2)

void Fun(long num){ } (3)

void Fun(short sh, long on) {} (4)

void Fun(long on, short sh){ } (5)

然后针对前面提到的5种匹配的情况来对照下.

(一)Fun("arwen"); //匹配void Fun(string name){ }

此时先挑选出函数1,2,3做为候选.然后直接匹配到(1),于是OK

(二)short num = 211;

Fun(num); //匹配void Fun(int num){ }

也是先匹配到1,2,3然后没能找到完全匹配short类型的.于是就做隐式转换.short可转换成char,int,long.于是匹配到了(2)和(3).此时要按照规则来选哪一个最合适了.一般是字节数相差最少的是最优选择.short是2个字节,int是4,long是8.于是short转换为int最优.于是OK就选(2).当然如果假设没有函数(2)的话应就会选(3)的

(三)int num = 918;

Fun(num , num); //匹配出错.没找到合适的.

它是先匹配到(4)和(5),然后做类型转换int分别转换成short和long就匹配到(4),int 分别转换成long ,shot就匹配到(5).然后接着判断哪个匹配最佳.结果傻眼了.两个貌似一样的好.

于是就报错,说The call is ambiguous between the following methods or proerties.

C#由于对隐式类型转换管得比较严,只有转换时没有任何精度损失时才可以转.所以相对而言简单一点.而C++任何数值类型都可以隐式转.此时匹配起来更麻烦.更复杂.

不过原理完全一样.

重载函数好处与注意事项

好处

重载函数的好处是为我们取名省了很多事,不用给每一个类似功能的函数取个啥有意义的名字.而且用起来也方便,只要记住一个函数名字就行,具体调用的时候开发环境工具会给你提示要传入的参数.

重载函数在C#中的用处更大一点,比如如果一个函数要传很多个参数进去,而用些参数不重要,用户根据不关心.搞个默认值就行了.这就必须用重载函数让用户可以选择传不同的参数.而C++中由于有默认实参的功能,所以对重载函数的需求相对不那么重要.

注意事项

但通过上面的例子我们发现函数重载一多会容易出现匹配出错的可能.所以如果重载的函数如果容易出现这种情况,比如有几个参数都是数值类型.你可考虑别用重载,起个另外的函数名字得了.这是从写重载函数的角度考虑.

而从函数用户的角度考虑的话,我们调用函数时要看下函数要求传啥参数,如果我们不是传完全匹配的参数就先自己做下显式转换.然后再传,这样就不会出错

函数指针匹配问题

在C++中有函数指针的概念.那我们声明一个函数指针时,然后匹配的话规则跟上面也是完全一样.

不过C#中没有指针的概念,但c#有个叫代理(delegate)的机制.有点类似于函数指针,它就霸道很多,如果不能完全匹配就直接报错,才不管啥先隐式转换再匹配呢.

举例

delegate void myDelegate(short sh);//定义个代理

然后有函数

void Fun(int num){ }

声明一个代理类型并初始化.myDelegate arwen = Fun;

short sh = 12;

arwen(sh); //报错.代理表明它指向一个返回值为void,形参为short类型的.但你是int类型的函数.所以不能匹配.

分享到:
评论

相关推荐

    C#通过PInvoke调用c++函数的备忘录的实例详解

    目前知道的情况被调用的C/C++函数只能是全局函数 不能调用类中的成员方法 被调用的C函数必须使用extern “C“包含,保证...能否调用重载的c++函数导出还没有试验,目前找到的信息看还是不行 字符串只支持C里的char* w_

    C++入门经典(第9版) ([美]Walter Savitch著) 中文pdf完整扫描版[302MB]

    第11章 类中的友元函数、重载操作符和数组 第12章 独立编译和命名空间 第13章 指针和链表 第14章 递归 第15章 继承 第16章 异常处理 第17章 模板 第18章 标准模板库 附录1 C++关键字 附录2 操作符的优先级 附录3 ...

    C++: The Complete Reference,4th Edition

    本书以一种清晰而易懂的方式,全面介绍了C++语言的各个方面,如关键字、语法、函数、类和库,以及一些C++高级特性,如重载、继承、虚拟函数、命名空间、模板、RTTI(运行时类型信息),以及STL(标准模板库)等。...

    C#科学计算讲义

    C#科学计算讲义-宋叶志-人民邮电出版社 内容概要 《C#科学计算讲义》较为详细地介绍了科学计算方法,并对算法给出了源代码。关于算法部分主要介绍了线性方程组的迭代解法与直接解法、正交变换与最小二乘计算方法、...

    C#中的泛型与C++中的模板

    一个同事问我C#中有没有模板函数,他想写一个函数能够处理不同的类型,里面算法一样,如果要重载实现的话,造成大量重复的代码,而且扩展性不好。我说肯定有啊,你可以上网搜一下,结果他说没搜到,而我对C#根本不熟...

    PHP实现的函数重载功能示例

    本文实例讲述了PHP实现的函数重载功能。...由于实现函数的重载对提高开发效率很有帮助,如果能象C#或者C++那样,那就非常好了。事实上,PHP的提供了一个魔术方法,mixed __call ( string name, array argumen

    浅析C#与C++相关概念的比较

    4、C#中可以通过关键字sealed把一个类声明为密封类,即不能被作为父类被继承出派出类,在C++中可通过把构造函数声明为private,让其不能被作为父类被继承出派出类,且同时不能实例化,但可通过类的

    C#实现的计算器小程序

    一个简单用C#编写的计算器 实现基本功能 虽不是很强大但仅供大家参考

    在c++中实现属性

    本文试着在C++中不使用任何扩展技术模拟C#(或其他语言)中的属性特征。大多数在C++实现属性的库和编译器使用扩展技术,如Managed C++或C++ Builder,或者他们使用如通常函数的set和get方法,但那不是属性。 详述 ...

    C#微软培训资料

    1.2 .NET 与 C#.6 1.3 C#语言的特点.8 1.4 小 结 .11 第二章 运行环境 全面了解.NET.12 2.1 .NET 结构.12 2.2 公用语言运行时环境与公用语言规范.13 2.3 开 发 工 具 .17 2.4 小 结 .19 第三章 编写...

    Visual C++ 2010入门经典(第5版)--源代码及课后练习答案

    8.4.6 重载函数调用操作符 388 8.5 对象复制问题 389 8.5.1 避免不必要的复制操作 389 8.5.2 应用rvalue引用形参 392 8.5.3 命名的对象是lvalue 394 8.6 类模板 399 8.6.1 定义类模板 400 8.6.2 根据类模板...

    云南大学软件学院C#实验

    云南大学软件学院C#实验,包括:单词计数、学生信息管理、委托、函数重载、继承和多态、异常处理、接口,共7个实验。

    Visual.C#2010从入门到精通

    学习以c#的必备书 本书介绍了如何使用Visual C++ 6.0编写Windows应用程序。全书内容全面、结构清晰、由浅入深、注重实用,并结合了大量的实例,以方便读者理解。本书既包含菜单、鼠标、键盘等基本操作,又包含图形...

    C#中重载相等(==)运算符示例

    在 C++ 里面,运算符重载可以写在类的外面,当 intellisense 不工作的时候,找到一个运算符的重载函数是一件相当头疼的事情。这个问题在 C# 中改善了不少,因为运算符重载一定要写在类内,而且 intellisense 很强大...

    棋盘覆盖C# (图形保存)

    近日在csdn上下了一个VC写的棋盘覆盖,不过VC写的那个没有对paint函数重载,于是用C#改进了一个。

    C#版编写的俄罗斯方块游戏

    C++是游戏编程的首选语言,但我相信C++能做到的C#也能做到。 本篇介绍用C#编写一个俄罗斯方块程序的原理,以及在C#里面播放声音,保存游戏设置的方法。 游戏界面预览: 菜单预览: 自定义每个小方块...

    c#类的使用示例

    C#不能够像C++一样在数据声明时调用构造函数,必须使用Myclass temp = new Myclass()来调用构造函数; C#不支持多重继承关系, 也就是说,一个派生类不允许有多个基类。简单点就是,父亲可能有好多儿子(父类可以...

Global site tag (gtag.js) - Google Analytics