什么是命名空间
命名空间是用于表示一组标识符的可见范围,用于解决标识符重定义的问题。
命名空间的使用
例子引入
我们正在进行多人开发或大项目开发时,可能会出现标识符重定义的问题,也就是变量名、函数名、类名可能会存在重复的问题。
1 | /* file_a.cpp */ |
1 | /* file_b.cpp */ |
可以看到
file_a.cpp
和file_b.cpp
中同时出现了同名函数且不构成函数重载。如果我们此时进行编译的话会不通过,会出现链接错误并提示你: duplicate symbols。
虽然这个例子举得可能不恰当,似乎并不会有人这样做,但是相信我,你一定会出现类似问题的,这也是命名空间存在的意义。
命名空间的语法
- 声明一个命名空间
namespace 命名空间名 { /\* some identifiers \*/ }
1 | namespace ns { |
- 访问命名空间中的内容
命名空间名::标识符
1 |
|
使用 using 使用命名空间
我们可以使用 using
关键字使用命名空间,使得命名空间中的内容在此作用域内可见,从而不需要通过作用域运算符访问命名空间中的内容。
- 使用整个命名空间
using namespace 命名空间名;
1 |
|
- 使用命名空间中的部分内容
using 命名空间名::标识符;
1 |
|
在定义和使用命名空间时的注意点
命名空间的大括号后面不需要分号结束。
命名空间内的缩进可以根据个人喜好或公司代码规范来调整。
可以在一个文件内出现多个命名空间,也可以在多个文件内出现同一个名字的命名空间,但同名命名空间内绝对不能出现重名的标识符。
- 一个文件出现多个命名空间 ✅
1
2
3
4
5
6
7
8
9
10
11
12
namespace aaa {
int a = 10;
}
namespace bbb {
int a = 20;
}
int main() {
std::cout << aaa:a << endl; // 10
std::cout << bbb:a << endl; // 20
}- 多个文件中出现同一个名字的命名空间 ✅
1
2
3
4/* file_a.cpp */
namespace aaa {
int a = 10;
}1
2
3
4/* file_b.cpp */
namespace aaa {
int b = 20;
}这样做并不好,因为这样虽然编译能通过,但是在
file_a.cpp
中并不能够访问到file_b.cpp
中的那部分。所以正确的做法是将它们放在不同的头文件中来方便我们引入,如果你需要在命名空间中存放的内容并不多,且内容同属一个模块,那么直接放在一个文件中即可。
- 多个文件中出现同一个名字的命名空间,并出现了重名的标识符 ❌
1
2
3
4
5/* file_a.cpp */
/* 错误示范 */
namespace aaa {
int a = 10;
}1
2
3
4
5/* file_b.cpp */
/* 错误示范 */
namespace aaa {
int a = 20;
}这样做就等同于在一个作用域内声明/定义了同名标识符
1
2
3
4
5/* 错误示范 */
namespace aaa {
int a = 10;
int a = 20;
}在
using
命名空间时,也请保证在一个作用域内不会出现可见的多个同名标识符,否则编译不通过,出现链接错误。