C++命名空间实例解析

2020-01-06 12:50:04于丽

一个未命名的命名空间可以在某个给定的文件内不连续,但是不能跨越多个文件。也就是说,未命名的命名空间仅在特定的文件内部有效,其作用范围不会横跨多个不同的文件。另外,由于未命名的命名空间它没有名字,所以其中定义的名字的作用域与该命名空间所在的作用域相同:


int i;  // i的全局声明 
namespace { 
  int i; 
} 
i = 10; // 错误,二义性 


namespace local { 
  namespace { 
    int i; 
  } 
} 
local::i = 42; // 正确 

二、使用命名空间

对命名空间中成员的引用,需要使用命名空间的作用域运算符(::)。但是,像namespace_name::member_name这样使用命名空间的成员非常烦琐,我们需要使用一些其他的更简便的方法。

1、命名空间的别名

有些命名空间的名字很长或者命名空间嵌套了很多层,我们可以为其设定一个较短的同义词,也就是别名:


namespace cln = cpluslus_learning_namespace; 
namespace Qlib = outer::inner::QueryLib; 

2、using声明

一条using声明(using declaration)语句一次只引入命名空间的一个成员:


using 命名空间名::[命名空间名::……]成员名;  // 例如 using OLib::List; 

3、using指示

using指示(using directive)和using声明不同的地方是,我们无法控制哪些名字是可见的,因为using指示会使得某个特定的命名空间中所有的名字都可见:


using namespace std;  // 引入命名空间std 

使用命名空间主要是为了防止名字冲突,如果随意使用using指示注入命名空间的所有名字,将重新引入名字冲突的问题。另外,using声明和using指示在作用域上有区别:using声明是将一个成员引入当前命名空间作用域内;using指示是将所有成员引入当前和上一层命名空间作用域内:


namespace nsp {  // 命名空间 
  int i=16, j=15; 
} 
 
int j = 0;  // 全局变量 
 
int main() 
{ 
  using namespace nsp;  // 如果使用j,将在::j和nsp::j之间产生冲突 
  std::cout << j; 
  return 0; 
}

如果将using namespace nsp;改成using声明using nsp::j;则会正确输出15。