Cplusplus 简明教程

Namespaces in C++

想象这样一个场景:在同一个班级中有两个同名的 Zara。无论何时我们需要明确地区分她们,都必须使用她们的名字来添加一些其他信息,例如她们居住的不同区域或她们的母亲或父亲的名字等。

在您的 C++ 应用程序中也会出现这种情况。例如,您可能编写的某个代码有一个名为 xyz() 的函数,而另一个可用库也具有相同函数 xyz()。现在,编译器无法知道在您的代码中您指的是哪个版本的 xyz() 函数。

namespace 旨在克服这种困难,并用作包含在不同库中具有相同名称的相似函数、类、变量等的附加信息,以便区分它们。使用命名空间,您可以定义名称的定义上下文。从本质上讲,命名空间定义一个作用域。

Defining a Namespace

命名空间定义以关键字 namespace 开头,后跟命名空间名称,如下所示 −

namespace namespace_name {
   // code declarations
}

要调用这两个函数或变量的启用命名空间的版本,请在命名空间名称之前添加 (::),如下所示 −

name::code;  // code could be variable or function.

让我们看看命名空间如何作用于变量和函数等实体 −

#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

int main () {
   // Calls function from first name space.
   first_space::func();

   // Calls function from second name space.
   second_space::func();

   return 0;
}

如果我们编译并运行上述代码,这将产生以下结果:

Inside first_space
Inside second_space

The using directive

您还可以使用 using namespace 指令避免添加命名空间。此指令告诉编译器后续代码正在使用指定命名空间中的名称。因此,命名空间暗示了以下代码 −

#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }
}

// second name space
namespace second_space {
   void func() {
      cout << "Inside second_space" << endl;
   }
}

using namespace first_space;
int main () {
   // This calls function from first name space.
   func();

   return 0;
}

如果我们编译并运行上述代码,这将产生以下结果:

Inside first_space

“using”指令还可用于引用命名空间中的某个特定项目。例如,如果您打算使用的 std 命名空间中唯一的部分是 cout,则您可以按如下方式引用它 −

using std::cout;

后续代码可以在不添加命名空间的情况下引用 cout,但 *std * 命名空间中的其他项目仍需要按照如下方式显示明确 −

#include <iostream>
using std::cout;

int main () {
   cout << "std::endl is used with std!" << std::endl;

   return 0;
}

如果我们编译并运行上述代码,这将产生以下结果:

std::endl is used with std!

using 指令中引入的名称遵循常规作用域规则。此名称从 using 指令点到找到此指令的作用域的末端均可见。在外部作用域中定义的具有相同名称的实体将处于隐藏状态。

Discontiguous Namespaces

可以分几个部分定义命名空间,因此一个命名空间是由其单独定义的部分总和组成。命名空间的各个部分可以分布在多个文件中。

因此,如果命名空间的一部分需要在另一个文件中定义的名称,则必须声明该名称。编写以下命名空间定义会定义一个新的命名空间或向现有命名空间添加新元素 −

namespace namespace_name {
   // code declarations
}

Nested Namespaces

可以嵌套命名空间,您可以在另一个名称空间中定义一个命名空间,如下所示 −

namespace namespace_name1 {
   // code declarations
   namespace namespace_name2 {
      // code declarations
   }
}

您可以使用解析运算符按照如下方式访问嵌套命名空间的成员 −

// to access members of namespace_name2
using namespace namespace_name1::namespace_name2;

// to access members of namespace:name1
using namespace namespace_name1;

如果在以上语句中您使用了 namsepace_name1,那么这将使 namsepace_name2 的元素在以下范围内可用 −

#include <iostream>
using namespace std;

// first name space
namespace first_space {
   void func() {
      cout << "Inside first_space" << endl;
   }

   // second name space
   namespace second_space {
      void func() {
         cout << "Inside second_space" << endl;
      }
   }
}

using namespace first_space::second_space;
int main () {
   // This calls function from second name space.
   func();

   return 0;
}

如果我们编译并运行上述代码,这将产生以下结果:

Inside second_space