名字查找和名字隐藏

名字查找

每当一个变量或者一个对象出现,编译器都会进行名字查找(name lookup),以确认这个变量或对象的具体属性。一般情况下,程序会从变量出现的地方开始向上查找,由内向外查找各级作用域直到全局作用域,找到同名的变量声明即停止,若最终没找到则报错。

#include <iostream>
using namespace std;

int a = 0;

int main() {
	string a = "1";
	cout << a << endl; // 在main函数体内找到了a的声明,停止名字查找,输出为string的内容“1”
	return 0;
}

名字查找还受到作用域限定符::的影响,若变量之前出现了作用域限定,那么则会从限定的作用域内进行全局搜索,并且不会查找其他位置。如果::之前没有出现作用域名,那么就会在全局作用域查找。

#include <iostream>
using namespace std;

int a = 0;

int main() {
	string a = "1";
	cout << ::a << endl; // 限定a的查找从全局作用域开始,那么首先被找到的是a的int类型定义,程序输出0
	return 0;
}

此外,由于在找到同名声明之后便会停止查找,函数匹配出现在名字查找之后。

#include <iostream>
using namespace std;

void print() { cout << "1" << endl; }

int main() {
	int print;
	print(); // 试图调用print(),但程序无法通过编译,这是因为在找到int型变量print之后,
             // 编译器就停止了查找,把一个变量当作函数调用显然是错误的
	return 0;
}

名字隐藏

从上面的例子可以看出,在不使用访问限定符的情况下,内层作用域的变量会隐藏外层作用域的同名变量,即发生了名字隐藏。名字隐藏还会发生在类的继承过程,在子类定义和父类同名的成员时,会隐藏从父类继承来的成员,名字隐藏并不是什么特性,相反,名字隐藏会增加程序编写的难度。我们应该养成良好的命名习惯,避免出现名字隐藏。

posted @ 2023-04-03 20:16  Bdathe  阅读(56)  评论(0)    收藏  举报