命名空间理解
转自:https://bbs.csdn.net/topics/300176441,https://blog.csdn.net/qq_41230365/article/details/80191964
1.头文件不能使用using
在一段代码的开头引入命名空间的原因则是加强程序模块化,和减少命名冲突。
如果把using声明用在了头文件中,会让命名冲突问题更加恶化,因为命名冲突问题早晚都会在一个调用关系非常非常远的模块中神不知鬼不觉的出现,而你可能需要查三层调用才可以找到原因所在, 一个头文件包含了另一个直接使用using声明的头文件可以导致命名空间被立刻污染掉,任何一个使用命名空间的文件如果使用了std命名空间的内容,都会导致这类问题。
代替做法:
- 使用typedef:
std::map<std::string, long> clientLocations; typedef std::map<std::string, long> ClientNameToZip; ClientNameToZip clientLocations;
- 使用using符号,限制作用域
using std::string;
但上述声明仍不能放到头文件中。应该使用作用域来限制下它的可见性,来确保你的using声明真的只在第一次做using声明的地方有效。例如:
namespace bar { struct zzz { … }; } class foo //bar命名空间的作用域在该类中 { using namespace bar; zzz m_snooze; // Pulls in bar::zzz }; void temp() { using namespace std; //把作用域限制在一个函数中 string test = "fooBar"; }
可以把using的作用域限制到需要使用它的代码中,而不是把它放到代码的公共空间中。 你的工程越大,确保模块化,和最小化不可预料的负面影响就显得越发重要。
2.作用
using namespace用来确定编译时缺省查找的名字空间。
https://blog.csdn.net/Fourier_Legend/article/details/82225279
#include <stdlib.h> #include <iostream> namespace detail // 定义一个namespace { const int i=99; } namespace ant // namespace 嵌套 { namespace blas { const int i=0; }//end blas const int i=3; namespace detail { const int i=33; void test() { std::cout<<"i:"<<i<<std::endl; // 33 std::cout<<"::detail::i"<<::detail::i<<std::endl; // 99 从根命名空间开始的detail空间 std::cout<<"detail::i"<<detail::i<<std::endl; // 33 当前的detail空间 std::cout<<"::ant::blas::i:"<<::ant::blas::i<<std::endl;// 0 ::ant 表根命名空间 std::cout<<"ant::blas::i"<<::ant::blas::i<<std::endl; // 0 std::cout<<"blas::i"<<blas::i<<std::endl; // 0 平级 //std::cout<<"::blas::i"<<::blas::i<<std::endl; // error std::cout<<"ant::i"<<ant::i<<std::endl;// 3 } }// end detail }//end namespace ant using namespace std; int main() { ant::detail::test(); // 引用test() 需要:: 限定符 return 0; }
从上面的代码来理解,根命名空间就是它不被别的命名空间嵌套,是第一级别的。嵌套命名空间using方法:
namespace ABC { void fun1(){printf("this is fun1.\n");} namespace map { void fun2(){printf("this is fun2.\n");} } } using namespace ABC; using namespace ABC::map; //使用两个namespace, 相当于把两个空间中的变量和函数都抠出来,供本函数使用 int _tmain(int argc, _TCHAR* argv[]) { fun1(); fun2(); return 0; }
3.嵌套命名空间