域和名字解析是编译时刻的概念,它们应用在程序文本的某一部分上这些概念给出了源文件中的程序文本的意义,编译器根据域规则和名字解析规则解释它所读入的程序文本.
局部域
包含在函数定义或者函数块中的程序文本部分。每一个函数都有一个独立的局部域,在函数中的每个复合语句或块也有一个独立的局部域。

局部域内的名字解析:首先查找使用该名字的域,如果找到一个声明,则该名字被解析。如果没有找到,则查找包含该域的 域,这个过程会一直继续下去(查找顺序查找域的顺序由内向外),直到找到一个声明或已经查找完整个全局域。如果后一种情况发生 即没有找到该名字的声明,则这个名字的用法将被标记为错误。

有一些语句允许在它的控制结构中定义变量,for 循环允许在它的初始化语句中定义一个变量,该变量只在for循环内部可见。也可以在一个if 或switch 语句,以及在while的条件中声明变量。(这是标准C++中的情况,在标准C++之前并非如此)

类域
每个类定义都引入了一个独立的类域,在类体中每一个类成员的声明都向它的类域中引入了一个成员名。如果类成员的定义出现在类体之外,则跟在被定义的成员名后面的程序,直到该成员定义结束,都被认为是在类域之中。

在类定义中用到的名字必须在使用前首先被声明,但是有两个例外:
1. 对于被用在inline 成员函数定义中的名字。
     inline 成员函数中名字解析分两步①.函数声明(返回类型和参数表)在类定义中出现的位置,即函数返回类型和参数类型必须在使用前被声明。②.函数体在完整类域中,函数体内的变量类型在整个类中解析。
2. 被用作缺省实参的名字。
     缺省实参在整个类域中解析,但是缺省实参引用的应该是静态成员,因为非静态成员在使用前必须绑定到某一对象或对象指针上。

命名空间域:
不包含在函数声明、函数定义或者类定义内的程序文本部分。是用来定义作用域的一个声明性区域。由关键字namespace来创建。名字空间定义可以是非连续的

程序的最外层的名字空间域被称作全局域,对象、函数、类型以及模板都可以在全局域中定义;也可以利用名字空间定义 namespace definition 来定义用户声明的名字空间,它们被嵌套在全局域内,用户声明的名字空间可以包含对象、函数、类型和模板的声明与定义,以及被嵌套其内的用户声明的名字空 间。

在C++中可以用未命名的名字空间(也称匿名名字空间)声明一个局部于某一文件的实体。未命名的名字空间以关键字namespace 开头,后面没有名字。未命名名字空间的成员与被声明为static 的全局实体具有类似的特性(在C 中被声明为static 的全局实体在声明它的文件之外是不可见的)。

名字空间的定义不一定是连续,同一个名字空间的定义可以跨越几个不同的程序文本文件。不同程序文本文件的名字空间定义也可以积累起来。但是,未命名的名字空间的定义局部于一个特定的文件,不能跨越多个文本文件(相当于c中的static全局对象,仅在本文件内可见)

在外围名字空间中声明的实体被嵌套的名字空间中声明的同名实体所隐藏(类似于嵌套域中的声明隐藏外围域中的声明

using 声明以关键字using 开头后面是名字空间成员名, 但是一次只能引入一个名字空间成员.
using 声明同其他声明的行为一样:它有一个域,它引入的名字从该声明开始直到其所在的域结束都是可见的。using 声明可以出现在全局域和任意名字空间中,同时它也可以出现在局部域中。与其他声明一样,using 声明引入的名字有以下特性:

1. 它在该域中必须惟一
2. 由外围域中的声明引入的相同名字被其隐藏
3. 它被嵌套域中的相同名字的声明隐藏

using指示符以关键字using 开头后面是关键字namespace 然后是名字空间名。它使名字空间成员变得可见,就好像是在被定义之外的地方声明一下。需要注意四个问题
1.using 指示符是域内的
2.using 指示符引入的名字空间中如果有成员与所在域内的对象实体同名,只有在使用时才能被检测到错误。
3.对名字空间中的成员使用限定修饰名不受using 指示符的影响。
4.using 指示符所在域中的局部变量可以隐藏名字空间中的成员。

需要体会在不同位置使用using declarations(声明)和using directives(指示符)的区别
using 声明:它保留了该名字空间域,但是将成员名与一个局部同义词相关联。
using 指示符:其效果相当于去掉了该名字空间

标准C++库中的所有组件都是在一个被称为std 的名字空间中声明和定义的。在标准头文件如<vector>或<iostream> 中声明的函数对象和类模板都被声明在名字空间std 中。

名字解析

1.类域中名字解析
用在类定义中的名字(除了在inline 成员函数定义中的名字和缺省实参的名字)其解析过程如下:
①在名字使用之前出现的类成员的声明应予以考虑.
②如果步骤1 的解析没有成功,则在类定义之前的名字空间域中出现的声明应予以考虑.

被用在类成员函数定义中的名字的解析过程如下:
①在成员函数局部域中的声明首先被考虑;
②如果在步骤1中的解析不成功,则考虑所有的类成员声明;
③如果在步骤2中的解析不成功,则考虑在成员函数定义之前的名字空间域中的声明(而不只是出现在类定义之前的声明)
如果构造函数在类定义之外被声明,则名字解析的第3 步不但要考虑出现在类定义之前的全局域中的声明,而且还要考虑出现在成员函数定义之前的全局域中的声明.

用在类静态成员定义中的名字解析过程如下:
①考虑所有类成员的声明。
②如果第1步失败,则考虑在静态成员定义之前的名字空间域中出现的声明。
在第2步期间编译器考虑出现在静态数据成员定义之前的名字空间域中的声明而不只是出现在类定义之前的声明。


被用在嵌套类的定义中的名字(除了inline 成员函数定义中的名字和缺省实参的名字之外)其解析过程如下:
①考虑出现在名字使用点之前的嵌套类的成员声明;
②如果第1 步没有成功,则考虑出现在名字使用点之前的外围类的成员声明;
③如果第2 步没有成功,则考虑出现在嵌套类定义之前的名字空间域中的声明;
如果在全局域中,在外围域类之外定义嵌套类,则外围域类的所有成员都已经被声明完毕,因而编译器将考虑外围域类内的所有声明

被用在嵌套类的成员函数定义中的名字,其解析过程如下:
①首先考虑在成员函数局部域中的声明;
②如果第①步没有成功,则考虑所有嵌套类成员的声明;
③如果第②步没有成功,则考虑所有外围类成员的声明;
④如果第③步没有成功,则考虑在成员函数定义之前的名字空间域中出现的声明.

在局部类体内(不包括成员函数定义中的)的名字解析过程是:在外围域中查找出现在局部类定义之前的声明。在局部类的成员函数体内的名字的解析过程是:在查找外围域之前,首先直找该类的完整域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值