二、C++复习——命名空间
命名空间就是为类型、函数、变量提供一个作用域限制。
1 命名空间的定义
注意:定义命令空间时,结束时不要加分号namespace 命名空间名字 {
...
}
2 命名空间的使用
由于使用命名空间后,变量的作用域被限定,所以在使用变量时,就需要通过特定方式来完成。需要用到 :: 域解析操作符 。
- 暴露整个命名空间中的变量
using namespace name;
- 暴露命名空间中的某个变量
using name::variable;
- 使用指定变量
name::variable
- 直接使用
::全局变量
,使用::
前缀来访问一个变量或函数指的是对全局命名空间的访问。全局命名空间是最外层的命名空间,它包含所有不属于任何其他命名空间的变量、函数、类型等。
3 用法总结
3.1 :: 全局变量
该项目test01目录在 /assets/CPlusPlus/01_namespace/test01_02/
使用::
前缀来访问一个变量或函数指的是对全局命名空间的访问。全局命名空间是最外层的命名空间,它包含所有不属于任何其他命名空间的变量、函数、类型等。
这部分内容通过 ns.h
、ns.cpp
、main.cpp
三个文件编写证明。
3.2 inline内联命令空间
该项目test02目录在 /assets/CPlusPlus/01_namespace/test01_02/
C++11 标准中引入了一种新的嵌套命名空间,称为内联命名空间(inline namespace)。和普通的嵌套命名空间不同,内联命名空间中的名字可以被外层命名空间直接使用。也就是说,我们无须在内联命名空间的名字前添加表示该命名空间的前缀,通过外层命名空间的名字就可以直接访问它。
定义内联命名空间的方式是在关键字 namespace 前添加关键字 inline。
优点:实际上,该特性可以帮助库作者无缝升级库代码,让客户不用修改任何代码也能够自由选择新老库代码。3.3 多文件命名空间合并
不同头文件中也可以使用名称相同的命名空间(也就是说,分散在不同头文件中的同名命名空间会合并为一个),但前提是位于该命名空间中的成员必须保证互不相同。
该项目目录在 /assets/CPlusPlus/01_namespace/test03/
3.4 头文件全局变量多定义
比如有三个文件,h1.h
、h2.h
、main.cpp
。其中:
/* filename: h1.h */
namespace demo {
int a = 100;
}
/* filename: h2.h */
namespace demo {
int b = 200;
}
/* filename: main.cpp */
#include "h1.h"
#include "h2.h"
int
main (int argc, char *argv[]) {
std::cout << demo::a << std::endl;
std::cout << demo::b << std::endl;
return 0;
}
为什么以上内容编译没有问题呢?
答:因为只有 main.cpp
这一个源文件包含了进行了全局变量a和b的初始化。如果还有h1.cpp
或者h2.cpp
,并且包含各自的头文件,则会出现多重定义的问题。
3.4.1 关于多个头文件都有相同的命名空间
我们可以参考 geos
库(OpenCV其实也一样)的实现,进行简要的分析:
-
整个库就是
geos
,所以所有的变量定义,都是在namespace geos
中,然后再根据每层的功能,分各自的命名空间和变量。 -
比如有个:
geom
部分,所以namespace geos
中嵌套了namespace geom