什么是名称查找机制?
它的核心是编译器用来确定给定名称对应的过程 - 将其作为变量或函数或其他语言结构。它必须找到名称所指的基础语言结构。
例如当您调用函数printf()时,编译器必须找到printf的声明,以便它了解它是什么并且可以正确编译它。
如前所述,C++使用各种名称查找机制,您可以在Google上很容易地找到有关它们的信息。*也有一些基本信息:http://en.wikipedia.org/wiki/Name_resolution
名称查找是识别名称意味着什么的过程。名称查询的目的有两个代码
例如,如果你有这样的代码的
- 歧义解析
T(a);
这取决于是否
T
是否为类型:如果是类型,则为a
的声明,如果不是类型,则将其解释为函数c所有。某些名称表示类型或模板。一般来说,无论何时遇到名称,都必须在继续解析包含它的程序之前确定该名称是否表示这些实体之一。确定这个的过程称为名称查找。
名称查找将名称的使用与该名称的声明(3.1)相关联。
有名称查找两大类
- 不合格的名称查找是:从目前的范围开始,一个名称抬头,如果一个类的内部逃逸到封闭范围和基类。不从特定的命名范围开始。该查找表格一找到名称就会停止。因此,内部作用域(或类)中的名称隐藏了在外部作用域(或基类)中找到的名称。
- 限定名称查找:使用
::
运算符在给定范围内查找名称。
其他一些形式存在,如查找该点或箭头后会出现一个名称(如
ptr->foo
)或查找在class foo
名(其中无类型名称将被忽略)。一种特别有趣的形式是argument dependent lookup,用于根据函数调用中使用的参数类型来查找函数声明。名称查找找到声明后,会查看它的属性以及程序是否可以使用它。
只有名称查找,函数重载解析(如果适用)和访问检查后,已成功通过名字的声明引入的属性在表达式处理进一步使用
因此名称查找会发现私有类成员,但是如果您使用这些名称(如果您无法访问它们),则代码将被拒绝。即使基类与公共访问具有相同的名称,也是如此 - 这是因为如果名称在查找名称时停止在派生类中,名称查找将停止。
关于不合格和合格的有趣点加上后期属性检查(其中令人头痛的“超载方法隐藏正确的基础”跳入。) 有趣的视频通过Stl,关于名称查询: https://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n – 2012-11-04 16:33:38
我不知道你是否要求类比来描述名称查找。但我会对上述问题给出一个可能的答案。 在深入研究名称查找机制之前,我们先将两个概念映射为趣味和使用。
- 范围 - >目录
- 对象 - >文件
我不想解释这个比喻的原因。以下面的字面思考方式,范围由目录每次范围遇到。那么对象由文件。
#include <iostream>
using namespace std;
namespace Newton{
double distance, time;
double velocity(const double &, const double &);
}
namespace Einstein{
double distance, time;
double velocity(const double &, const double &);
}
int main()
{
using namespace Newton;
double s(10), t(10);
velocity(s,t);
return 0;
}
double Newton::velocity(const double & s, const double & t){
distance = s;
time = t;
cout << "Calculation by Newton" << endl;
return distance/time;
}
double Einstein::velocity(const double & s, const double & t){
distance = s;
time = t;
cout << "Calculation by Einstein" << endl;
return distance/time;
}
在这段代码中,velocity
是什么执行?我们在main()
的社交中遇到velocity
功能。如果您在文件资源管理器中将其命名为路径名称,则velocity
实际上是/Main/velocity
。当然,如果您检查/Main/
下的对象名称,仍然有两个双重对象,s
和t
,以及一个名称空间对象Newton
。如果列出/Main/double/
下的对象名称,我认为内置函数与名为velocity
的对象不匹配,这意味着,例如,不存在这样的对象 - /Built-in Types/double/velocity
。如果在/Main/Newton/
下再次列出对象的名称,则实际目录搜索为/Newton/
,因为它在那里被声明。然后,列出/Newton/
下的对象名称,我们找到两个双重对象,distance
和time
,以及一个名为velocity
的函数。是的,我们找到/Main/velocity
的候选功能。
我只能在C++中给出名称查找的类比。为了总结机制还有更多要补充的内容。
首先谷歌结果:http://www.lysium.de/blog/index.php?/archives/3-C++-name-lookup-mechanism.html – 2010-04-08 22:58:26
这是一个很大的问题。名称查找是C++更复杂的一个方面。它的一些部分(Koenig lookup)甚至以人名命名,就好像新领地曾经被勘探者命名。 – 2010-04-08 22:58:53
鲜为人知的事实类型 - Andrew Koenig是名字出现在C++标准中的唯一人 - 3.4.2/ – 2010-04-08 23:06:12