命名空间
命名空间是一个c++最基础的东西,但是往往基础的东西也比较难。命名空间作用是用来降低编译依赖(参考Eeffective c++ 条款23),就像标准命名空间内放了一堆东西比如 vector、set、map、string等。它们都是标准命名空间内的东西,但是我们往往使用的时候只需想使用什么包括什么头文件即可,不想使用的东西不必包含它。
比如我们想使用string就不必包含vector了,这就是通过命名空间做到的,因为c++完全可以把标准命名空间内的所有一坨东西都放到一个头文件内提供给用户使用,但是这种依赖太大了,代价也很大,会增加太多用户不想要的东西。所以我们使用命名空间+头文件就可以做到想使用什么就使用什么,我们可以把命名空间看作一个跨越多个头文件的一个特殊的头文件。
匿名命名空间
匿名命名空间内的标识符只能被本源文件内的代码所使用,不可被其他源文件的代码所使用。本质上源于编译器会为每个源文件内的匿名空间都起一个独一无二的名字,其他源文件自然不知道这个特殊的名字所以无法链接到其内部标识符。 主要因为 static 不可以修饰一个ADT类型,所以往往匿名空间用于ADT类型的局部链接。
test.cc
namespace {
void Fun()
{}
}
void Fun2()
{
Fun()
}
命名空间
头文件最好不要使用命名空间,这样会污染代码。因为可能包含该头文件的多个源文件内包含了其他的命名空间,这些命名空间内的一些标识符跟头文件的命名空间内的标识符命名冲突这样会编译错误。
test.h
namespace Test {
typedef int Int;
const int kint = 1;
};
test.cc
#include "test.h"
#include "test2.h"
using namespace Test;
namespace Test2{
typedef int Int;
const int kint = 1;
}
using namespace Test2;
typedef int Int;
const int kint=2;
报错:
test.cc:7: error: reference to 'Int' is ambiguous
test2.h:2: error: candidates are: typedef int Test2::Int
test.h:2: error: typedef int Test::Int
test.cc:7: error: reference to 'Int' is ambiguous
test2.h:2: error: candidates are: typedef int Test2::Int
test.h:2: error: typedef int Test::Int
test.cc:7: error: expected ';' before 'a'
test.cc:8: error: 'kinta' was not declared in this scope