名字查找

每当一个变量或者一个对象出现,编译器都会进行名字查找(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;
}

名字隐藏

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

最佳匹配

在函数调用时,首先对函数进行名字查找,在找到一个同名函数(假设不会出现命名冲突)时,编译器并不会停止查找,而是继续找出当前作用域的所有重载函数,然后根据最佳匹配规则,确定实际调用的函数。不同作用域的同名函数并不会被视为重载。最直观的例子是,类内的函数与类外的同名函数并不会形成重载。

在名字查找完成且不存在编译错误的情况下,编译器便开始确定与调用匹配得最好的函数。最佳匹配原则也很简单,实参类型与形参类型越接近,匹配得越好。

void print(int a) { cout << "int" << endl; }

void print(double a) { cout << "double" << endl; }

print(1); // 1是int类型,与print的int形参重载构成最佳匹配,故程序输出“int”

但如果同时有多个函数与调用形成匹配,那么编译器将报错。编译器不允许有二义性的调用存在。

void print(int a, int b, int c) { cout << "int" << endl; }

void print(double a, double b, double c) { cout << "double" << endl; }

print(1, 1.0, 1); // 编译器指出有多个函数重载匹配

C++:Name Lookup & Best Match的更多相关文章

  1. Mongodb:修改文档结构后出现错误:Element '***' does not match any field or property of class ***.

    Mongodb:修改文档结构后出现错误:Element '***' does not match any field or property of class ***. Mongodb是一种面向文档的 ...

  2. ElasticSearch查询 第四篇:匹配查询(Match)

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  3. fastDfs V5.02 升级到 V5.08版本后,启动报错:symbol lookup error: /usr/bin/fdfs_trackerd: undefined symbol: g_current_time

    /libfastcommon-1.0.36 # ./make.sh cc -Wall -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -g -O3 -c -o hash.o ...

  4. Neo4j 第九篇:查询数据(Match)

    Cypher使用match子句查询数据,是Cypher最基本的查询子句.在查询数据时,使用Match子句指定搜索的模式,这是从Neo4j数据库查询数据的最主要的方法.match子句之后通常会跟着whe ...

  5. 记录一次(xheditor-1.1.6-zh-cn.min.js)的错误:Cannot read property 'match' of undefined的问题解决

    由于使用了xheditor富文本框,且这个版本是2011年开发的系统,当时只有IE8,所以一切正常. 但是问题来了,今天使用IE11测试和谷歌浏览器测试,发现一直报这个错误: 且google了一下,没 ...

  6. Python自动化报错:IndentationError-unindent does not match any outer indentation level

    ​从错误中了解python语法: 如下图: 这个是因为python语句块是由格式来控制(缩进): 解决: 出现这个问题需要看下,自己写的python语句块是否格式缩进的问题 例如:如下图:构造函数前面 ...

  7. IndentationError:unexpected indent”、“IndentationError:unindent does not match any outer indetation level”以及“IndentationError:expected an indented block Python常见错误

    错误的使用缩进量 记住缩进增加只用在以:结束的语句之后,而之后必须恢复到之前的缩进格式. 经典错误,一定要注意缩进,尤其是在非界面化下环境的代码修改

  8. 错误: symbol lookup error: /usr/local/lib/libreadline.so.6: undefined symbol: PC

    su - root mkdir temp mv /local/ldconfig  apt-get update

  9. python正则表达式模块re:正则表达式常用字符、常用可选标志位、group与groups、match、search、sub、split,findall、compile、特殊字符转义

    本文内容: 正则表达式常用字符. 常用可选标志位. group与groups. match. search. sub. split findall. compile 特殊字符转义 一些现实例子 首发时 ...

随机推荐

  1. js 根据url 下载图片 前端js 实现文件下载

    1.H5 download属性 function downFile(content, filename) { // 创建隐藏的可下载链接 var eleLink = document.createEl ...

  2. MySQL for OPS 11:优化

    写在前面的话 不管是作为运维还是作为 DBA,我们的工作都不是写 SQL,搞业务.更多的还是如何实现又好又快的给开发提供一个数据库环境和保障数据的安全性.前面的文章中读写分离,高可用,建立索引,分库分 ...

  3. 一段不错的iframe自适应的代码直接拿来用了

    一段不错的iframe自适应的代码直接拿来用了 <?php echo " <!DOCTYPE html> <html lang='en'> <head&g ...

  4. java.lang.ClassNotFoundException: XXX (no security manager: RMI class loader disabled)

    在搞RMI远程发布,consumer去获取rmi远程服务的代理对象的时候出现了如下的错误 问题发现: 由于我发布的对象的包路径和获取的对象的包路径不一致,导致了这样的问题 解决方案: 包路径改为一致就 ...

  5. 用Python在Excel里画出蒙娜丽莎

    前言 文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: 麦麦麦造 PS:如有需要Python学习资料的小伙伴可以加点击下方链 ...

  6. Json互相序列化对象

    using System.ServiceModel; using System.ServiceModel.Web; using System.Runtime.Serialization.Json; u ...

  7. QT5.5+VS2013编译安装QtCharts (ZZ)

    环境 1.Windows 10 -x64: 2.MSVC 2013 -x64: 3.Qt5.5.1 -x86 and -x64. 编译过程 准备工作 1.安装ActivePerl 安装过程同一般软件安 ...

  8. MySQL报错注入总结

    mysql暴错注入方法整理,通过floor,UpdateXml,ExtractValue,NAME_CONST,Error based Double Query Injection等方法. 报错注入: ...

  9. 【转载】Gradle for Android 第六篇( 测试)

    由于现阶段Android开发趋于敏捷开发,再加上国内大大小小的互联网公司都在做app,导致很多这会是一个系列,所以如果你看完这篇文章,请看下列文章: 开发人员对单元测试没有基本的概念,但是本篇博文不会 ...

  10. ADB控制手机命令(adb命令)

    手机端配置tcp方式连接 su setprop service.adb.tcp.port 5555 stop adbd start adbd 首先使用管理员权限,然后打开监听5555端口 电脑端使用a ...