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

本文探讨了函数重载在C++与C#中的匹配规则,包括海选、精确匹配、隐式类型转换及匹配冲突解决策略。通过具体示例阐述了如何在不同场景下实现函数调用的正确匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

我们知道重载函数中可以形参个数相同,但类型不同.而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类型的函数.所以不能匹配.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值