Cplusplus 简明教程

Namespaces in C++

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

Consider a situation, when we have two persons with the same name, Zara, in the same class. Whenever we need to differentiate them definitely we would have to use some additional information along with their name, like either the area, if they live in different area or their mother’s or father’s name, etc.

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

Same situation can arise in your C++ applications. For example, you might be writing some code that has a function called xyz() and there is another library available which is also having same function xyz(). Now the compiler has no way of knowing which version of xyz() function you are referring to within your code.

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

A namespace is designed to overcome this difficulty and is used as additional information to differentiate similar functions, classes, variables etc. with the same name available in different libraries. Using namespace, you can define the context in which names are defined. In essence, a namespace defines a scope.

Defining a Namespace

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

A namespace definition begins with the keyword namespace followed by the namespace name as follows −

namespace namespace_name {
   // code declarations
}

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

To call the namespace-enabled version of either function or variable, prepend (::) the namespace name as follows −

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

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

Let us see how namespace scope the entities including variable and functions −

#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;
}

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

If we compile and run above code, this would produce the following result −

Inside first_space
Inside second_space

The using directive

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

You can also avoid prepending of namespaces with the using namespace directive. This directive tells the compiler that the subsequent code is making use of names in the specified namespace. The namespace is thus implied for the following code −

#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;
}

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

If we compile and run above code, this would produce the following result −

Inside first_space

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

The ‘using’ directive can also be used to refer to a particular item within a namespace. For example, if the only part of the std namespace that you intend to use is cout, you can refer to it as follows −

using std::cout;

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

Subsequent code can refer to cout without prepending the namespace, but other items in the *std * namespace will still need to be explicit as follows −

#include <iostream>
using std::cout;

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

   return 0;
}

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

If we compile and run above code, this would produce the following result −

std::endl is used with std!

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

Names introduced in a using directive obey normal scope rules. The name is visible from the point of the using directive to the end of the scope in which the directive is found. Entities with the same name defined in an outer scope are hidden.

Discontiguous Namespaces

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

A namespace can be defined in several parts and so a namespace is made up of the sum of its separately defined parts. The separate parts of a namespace can be spread over multiple files.

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

So, if one part of the namespace requires a name defined in another file, that name must still be declared. Writing a following namespace definition either defines a new namespace or adds new elements to an existing one −

namespace namespace_name {
   // code declarations
}

Nested Namespaces

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

Namespaces can be nested where you can define one namespace inside another name space as follows −

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

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

You can access members of nested namespace by using resolution operators as follows −

// 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 的元素在以下范围内可用 −

In the above statements if you are using namespace_name1, then it will make elements of namespace_name2 available in the scope as follows −

#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;
}

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

If we compile and run above code, this would produce the following result −

Inside second_space