C++学习笔记:默认命名空间与匿名命名空间
1.默认命名空间
1.1 默认命名空间的定义
默认命名空间也叫全局命名空间,所有没有置于某一具体命名空间下的代码即在默认命名空间下,例如func()
,main()
函数。
#include<iostream>
void func(void);
int main(int argc,char**argv)
{
std::cout<<"this is main"<<std::endl;
return 0;
}
void func(void)
{
std::cout<<"this is func"<<std::endl;
}
需要注意的是:
- 1.默认命名空间也是命名空间。
- 2.默认命名空间是全局的。
- 3.
main()
函数必须置于默认命名空间下。
1.2 默认命名空间引用其他命名空间
默认命名空间引用其他命名空间的方法与上一篇中的使用命名空间的方法是一样的,这里不再多说了。
1.3 默认命名空间引用自己
这个就是类似于C语言里简单的没有命名空间的函数调用,如下面的代码中main()
调用func1()
:
#include<iostream>
void func1(void);
int main(int argc,char**argv)
{
func1();
return 0;
}
void func1(void)
{
std::cout<<"this is func1"<<std::endl;
}
1.4 其他命名空间引用默认命名空间
其他命名空间引用默认命名空间同样使用::
,但是前面命名空间的名字是空白的,例如下面的代码中命名空间ns
引用默认命名空间下的func()
:
#include<iostream>
void func1(void);
namespace ns
{
void func2(void)
{
::func1();
}
}
int main(int argc,char**argv)
{
ns::func2();
return 0;
}
void func1(void)
{
std::cout<<"this is ::func1"<<std::endl;
}
2.匿名命名空间
2.1 匿名命名空间的定义
匿名命名空间和全局命名空间有些类似,他们都没有名字,但是全局命名空间不需要自己定义,而匿名命名空间需要自己去定义,方法就是namespace
后面没有空间名,直接就是 {}
:
namespace
{
void func(void)
{
std::cout<<"来自匿名命名空间的func()."<<std::endl;
}
}
2.2 匿名命名空间中引用其他命名空间
匿名命名空间引用其他命名空间的方法与上一篇中的使用命名空间的方法是一样的,这里不再多说了。
2.3 匿名命名空间中引用自己
直接用,无需添加命名空间名前缀,只要确保先声明后使用的顺序就没有问题。
2.4 其他命名空间中引用匿名命名空间
一般匿名命名空间定义于文件前面,类似于全局函数位置,之后的命名空间可以正常访问匿名命名空间中的内容,但是匿名命名空间的作用不在于此,而是在于跨文件访问的时候。因此其实对于单个文件内部,使用匿名命名空间与全局函数并无多大差别。
2.5 匿名命名空间的意义
- 1.匿名命名空间中的符号限于文件内部使用,不需要被外部引用。
- 2.匿名命名空间效果类似于全局变量和函数加
static
,但是比C
中的static
使用范围广,static
只能用于修饰函数名变量名,而不能用于修饰一个类型,如struct
,class
,而匿名命名空间则不局限于这些。 - 3.匿名命名空间虽然是一种特殊情况,但是用法逻辑上符合整个命名空间的一般原则。
3.命名空间的总结
- 1.命名空间的最终目标:解决全局名称冲突,同时提供合法互相访问的机制。
- 2.直接用法(语法),记住如何定义、如何声明、三种使用方法。
- 3.默认命名空间和匿名命名空间是特殊情况,均为符合一贯原则的特例用法。
- 4.头文件中一般不应包含
using
声明,因为头文件中的所有内容会被拷贝到所有引用它的文件中去,这样每一个引用了该头文件的源文件中都会有这个声明,对于一些程序来说,由于不经意间包含了这些名字,可能会产生一些意想不到的冲突。