C++中函数静态重载与名称查找




函数的静态重载只针对在同一个作用域中具有相同名称的函数才有效,不同作用域中的函数不行。在函数调用处,编译器会将同一作用域中具有相同名称的函数都作为候选函数,一旦找到函数名称,就不再从其他作用域中查找函数名称了。找到名称后,编译器才进行类型检查,查看调用处的函数与上面声明处的是否有一致的函数。
重要的是:名称查找优先于类型检查,举个例子:

int f1() {return 1;}

namespace
{
	int f1(int a) {return a + 1;}
	void f1() {}

	// 调用f1
	int s = f1();
}

上面定义了三个同名函数,一个定义在外层的全局作用域里面,两个定义在内部的匿名作用域里面。如果编译此段代码,编译器会报错,说调用的函数缺少参数,原因是:

  1. 编译器在调用f1的地方发现一个名称f1,因此,编译器就会去寻找名称f1的声明,其会优先在内层作用域(即此处的匿名作用域里)里查找名称f1,如果没有找到,则继续往外层查找,去到全局作用域里面找f1
  2. 编译器在内层作用域里面找到了f1的声明,且找到了两个,此时查找停止,编译器不再继续往外层查找(只要找到名称,就不会再继续往上层作用域里查找了,不论在内层找到了几个),编译器会把找到的这两个名称加入到候选匹配列表中;
  3. 名字查找完成后,就进行类型检查。编译器发现调用处的f1没有形参,且有返回值,而找到的两个f1的声明都不符合要求,此时编译器报错。

由上面可看出,函数静态重载只适用于同一个作用域中的同名函数,不同作用域中的同名函数不发生静态重载。实际上,内层作用域中的名称会隐藏其外层作用域中的相同的名称,而这个隐藏的原理应该就是上面3点的分析过程。
要记住的是:名称查找永远优先于类型检查,这个在类的继承体系中也是如此,比如继承体系中的非虚函数的调用:

class Base
{
	public:
	int f1(int a) {return a + 1;}
};

class Driv : public Base
{
	public:
	int f1() {return 2;}
};

int main()
{
	Driv d;
	int s = d.f1(); // 调用正确

	int s1 = d.f1(3); // 调用出错,编译器报出多加了形参
	return 0;
}

上述在main函数中调用f1时,也进行了上面所描述的3步。显然,在第一处调用的地方是正确的,因为编译器先找到了内层作用域(即类Driv的作用域)中的名称f1,此时,编译器不再继续往其父类作用域查找,因此编译器只找到了没有形参的f1,而有形参的f1并没有找。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【为什么还需要学习C++?】 你是否接触很多语言,但从来没有了解过编程语言的本质?你是否想成为一名资深开发人员,想开发别人做不了的高性能程序?你是否经常想要窥探大型企业级开发工程的思路,但苦于没有基础只能望洋兴叹? 那么C++就是你个人能力提升,职业之路进阶的不二之选。【课程特色】 1.课程共19大章节,239课时内容,涵盖数据结构、函数、类、指针、标准库全部知识体系。2.带你从知识与思想的层面从0构建C++知识框架,分析大型项目实践思路,为你打下坚实的基础。3.李宁老师结合4大国外顶级C++著作的精华为大家推出的《征服C++11》课程。【学完后我将达到什么水平?】 1.对C++的各个知识能够熟练配置、开发、部署;2.吊打一切关于C++的笔试面试题;3.面向物联网的“嵌入式”和面向大型化的“分布式”开发,掌握职业钥匙,把握行业先机。【面向人群】 1.希望一站式快速入门的C++初学者; 2.希望快速学习 C++、掌握编程要义、修炼内功的开发者; 3.有志于挑战更高级的开发项目,成为资深开发的工程师。 【课程设计】 本课程包含3大模块基础篇本篇主要讲解c++的基础概念,包含数据类型、运算符等基本语法,数组、指针、字符串等基本词法,循环、函数、类等基本句法等。进阶篇本篇主要讲解编程常用的一些技能,包含类的高级技术、类的继承、编译链接和命名空间等。提升篇:本篇可以帮助学员更加高效的进行c++开发,其包含类型转换、文件操作、异常处理、代码重用等内容。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值