C++中,名称可以是变量、函数、结构、枚举、类、以及类和结构的成员。使用名称空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染。
传统C++名称空间
声明区域
声明区域是可以在其中进行声明的区域。例如,全局变量的声明区域为其声明所在的文件;自动变量的声明区域为其声明所在的代码块。
潜在作用域和作用域
变量的潜在作用域从声明点开始,到其声明区域的结尾。
潜在作用域比声明区域小,因为变量必须定义后才能使用。
变量并非在其潜在作用域都是可见的,它可能被另一个在嵌套声明区域中声明的同名变量隐藏。变量对程序可见的范围被称为作用域。
#include <iostream>
int a = 1;
int main() {
int a = 3;
std::cout << ::a << std::endl; // 1
std::cout << a << std::endl; // 3
return 0;
}
例如全局变量a的潜在作用域是第2行~第8行;作用域是第2行~第3行;
定义同名局部变量后构成同名变量隐藏,但通过::a可以访问;
新的名称空间特性
定义
通过定义一种新的声明区域来创建命名的名称空间
- 可以是全局的,也可以嵌套定义,但不能位于代码块中。默认情况下链接性为外部(除非它引用了常量)
- 同一个工程中允许存在多个相同名称的命名空间编译器最后会合成同一个命名空间中。
使用
- 加命名空间名称及作用域限定符
- 使用using将命名空间中成员引入(using声明)
- 使用using namespace命名空间名称引入(using编译指令)
ps:
- using声明如果发生名称冲突会报错,而using编译指令会构成同名隐藏,局部版本将隐藏名称空间版本。
- using编译指令可传递。
- 可以给名称空间创建别名。
列如,namespace STD = std
可以通过这种技术简化对嵌套名称的使用 - 支持匿名名称空间。潜在作用域和全局变量相似,其特性提供了链接性为内部的静态变量的替代品。
例如全局静态变量static int counts;
可以这样代替namespace { int counts; }
最佳实践
- 使用在已命名的名称空间中声明的变量代替外部全局变量、静态全局变量
- 优先使用::或using声明