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

本文深入探讨函数静态重载的概念,解释在相同作用域中如何实现同名函数的重载,以及不同作用域中同名函数的行为差异。通过具体代码示例,分析编译器在名称查找与类型检查之间的优先级,揭示内层作用域如何隐藏外层作用域的同名函数。

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




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

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并没有找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值