初识C++之函数重载

最近开始学习C++,了解到它在C语言没有的一个特性 – 函数重载,这一特性使得c++的函数数量得以减少,减小了对名字空间的污染,另外对程序的可读性也有很大帮助。

那么c++的函数重载这一特性是怎么实现的,为什么不会发生命名冲突呢?别的函数在调用这些函数时编译器是怎么解析的呢?怎么知道它该调用哪一个函数呢?下面就这些问题来做一些简单解析。

1、什么是函数重载

C++允许在同一作用域内声明并实现几个名称相同,功能相似的函数,但必须保证这些函数的参数列表不同(参数个数不同、参数类型不同或者参数顺序不同)

根据上面的定义,判断哪些是正确的函数重载,哪些是错误的:

int Add(int a, int b)
{
    return a + b;
}

double Add(double a, double b)
{
    return a + b;
}

double Add(double a, int b)
{
    return a + b;
}

double Add(int a, double b)
{
    return a + b;
}

int Add(int a, int b)
{
    return a + b;
}

int Add(int a, int b, int c)
{
    return a + b + c;
}

double Add(int a, double b)
{
    return a + b;
}

double Add(int b, double a)
{
    return a + b;
}

int Add(int a, int b)
{
    return a + b;
}

double Add(int a, int b)
{
    return a + b;
}

①②③很容易得出都是正确的函数重载;
④乍一看,很像是满足了参数顺序不同这一条件,但仔细分析一下,函数在定义或声明是是可以省略参数名的,因为编译器只检查函数参数的类型与个数,并不会检查函数名。那么,④的两个函数就可以看做是一个,因为它们无法构成函数重载;
⑤看起来也很像啊,但它满足函数重载的任何要求了吗,另个函数参数列表完全是一样的,唯一不一样的就是函数的返回值不同,但仅仅返回不同是无法构成函数重载的的,因此,它们也无法构函数重载。

2、为什么需要函数重载

想一想我们的C语言里是怎么定义不同类型的数据的加法函数的:

int Add(int a, int b); –> int 型数据的加法函数
short Add(short a, short b); –> short 型数据的加法函数
double Add(double a, double b); –> double 型数据的加法函数

是不是感觉很麻烦,都是同一功能的函数,却要起不同的名字,正式基于这一点,c++允许实现函数重载,这样不仅同一功能的函数都能叫同一名字,而且节省了名字空间。

3、编译器如何解决函数重载的命名冲突

c++确实能支持函数重载,但编译器是怎么处理这种特性,使它们在编译后不会出现名字冲突的呢?

这里可以参考我的另一篇博客:
重载函数编译后的新名字
http://blog.csdn.net/ljx_5489464/article/details/50981773

4、编译器如何解析重载函数的调用呢?

上面我们知道了,编译器通过一定的机制使重载函数在编译后不会发生名字冲突,那么在调用这些重载的函数时,编译器是如何知道该调用哪一个的呢?

编译器一般需要依次按照下列规则来判断:
a. 精确匹配:参数列表完全匹配,或者只是做微不足道的转换,如数组名到指针、函数名到指向函数的指针、T到const T;
b. 提升匹配:即整数提升(如bool 到 int、char到int、short 到int),float到double
c. 使用标准转换匹配:如int 到double、double到int、double到long double、Derived*到Base*、T*到void*、int到unsigned int;
d. 使用用户自定义匹配;
e. 使用省略号匹配:类似printf中省略号参数

通过以上规则来进行选择:
①根据函数名确定候选函数集
②确定可用函数
③确定最佳匹配函数

如果在最有多个最佳匹配函数找到,调用将被拒绝(因为有歧义、模凌两可)。

本文参考:
http://www.cnblogs.com/skynet/archive/2010/09/05/1818636.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在C语言中,unordered_set的函数包括: - begin():返回一个迭代器,指向unordered_set的第一个元素。 - end():返回一个迭代器,指向unordered_set的末尾(最后一个元素的下一个位置)。 - insert(const K& key):将一个元素插入到unordered_set中,并返回一个pair对象,其中的iterator指向插入的元素,bool值表示是否插入成功。 - find(const K& key):查找unordered_set中是否存在指定的元素,如果找到,则返回一个指向该元素的迭代器;如果找不到,则返回end()。 - erase(const K& key):从unordered_set中删除指定的元素,如果删除成功,则返回true;如果删除失败(即元素不存在),则返回false。 需要注意的是,在C语言中,unordered_set的函数并不是直接在C标准库中提供的,而是通过自定义的unordered_set类实现的。所以,使用unordered_set函数之前,需要先引入相应的头文件,并使用对应的命名空间。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [初识C++之unordered_map与unordered_set](https://blog.csdn.net/Masquerena114514/article/details/129938734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [c++ unordered_set 函数参考](https://blog.csdn.net/weixin_46183779/article/details/119979647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值