简介
命令空间非常常见,各种面向对象语言都有这个词,C#中,Java中有package,甚至连数据序列化语言XML中也出现命名空间。
命名空间就是为解决C++中的变量、函数的命名冲突而服务的。网上有人比喻说命名空间的作用就相当于文件夹,归类用的。
首先要了解下作用域:
现代标准C++中作用域分4种,代码块({……},如复合语句和函数体)、类、全局和命名空间。
命名空间可以是全局的,也可以位于另一个命名空间之中,但是不能位于类和代码块中。所以,在命名空间中声明的名称(标识符),默认具有外部链接特性(除非它引用了常量)。
用法
1.命名空间重定向
#ifndef GFLAGS_GFLAGS_H_
namespace baz = ::foo::bar::baz;
#endif // GFLAGS_GFLAGS_H_
这种用法可以节省劳动,使用baz和使用::foo::bar::baz效果一样。
2.预编译指示
使用预编译指示的好处在于在程序中不必显式地使用命名空间限制符来访问变量。
using namespace std;
3.结合#ifdef重定向函数
在OpenCV中parallel_for_函数的调用中,如果编译时加上了tbb,那么通过#if HAVE_TBB将parallel_for_重定向到tbb中的parallel_for函数,否则使用的使用OpenCV自己的parallel_for_函数。
4.匿名namespace
namespace //没有名字
{
int i;
int add(int a,int b);
}
相当于
static int i;
static int add(int a,int b);
5.默认命名空间
#include<iostream>
int main(){
int i;
return 0;
}
没有显式指定命名空间,那么它们从属于默认的命名空间,有时也称为全局命名空间。
如何用好namespace
1.建议一
谷歌的代码风格规范中建议我们不要随便把变量、类型之类的放到全局命名空间中。因为如果是几千个工程师协同完成任务,代码达到上亿行时,要使程序能运行的话,必须解决命名冲突的问题,大家都为了省事而把变量都定义到全局命名空间中则会带来很多麻烦。
2.建议二
建议在.cc文件中使用匿名namespace,以避免链接时命名冲突。但不要在.h文件中使用匿名namespace。
3.建议三
不要使用using 指令如using namespace foo;,它容易使命名空间发生命名冲突。不要在.h文件中使用using指令,除非是仅内部使用的namespace,因为using指令会使得.h文件中的任何变量函数都可以被外界访问。原文“Do not use using-declarations in .h files except in explicitly marked internal-only namespaces, because anything imported into a namespace in a .h file becomes part of the public API exported by that file.”
例子如下:
// Shorten access to some commonly used names (in a .h file).
namespace librarian {
namespace impl { // Internal, not part of the API.
namespace sidetable = ::pipeline_diagnostics::sidetable;
} // namespace impl
}// namespace librarian
续:
匿名命名空间
匿名命名空间会被编译器赋予一个唯一的名称__UNIQUE_NAME_,命名空间里面声明的名称和变量会被编译器会跟这个唯一名称__UNIQUE_NAME_拼接。在别的文件中无法知道这个__UNIQUE_NAME_,因此其他文件也无法访问该命名空间中的变量。
以后再遇到了,继续更新。。。。