C++ 中的命名空间
设想这样一种情况:同一个类中有两个同名的人,Zara。每当我们需要明确区分他们时,就必须使用一些附加信息,例如地区、他们是否居住在不同地区,或者他们父母的姓名等等。
同样的情况也可能出现在您的 C++ 应用程序中。例如,您可能正在编写一些包含名为 xyz() 的函数的代码,而另一个可用的库中也包含相同的函数 xyz()。现在,编译器无法知道您在代码中引用的是哪个版本的 xyz() 函数。
命名空间旨在解决这一难题,它用作附加信息来区分不同库中具有相同名称的类似函数、类、变量等。使用命名空间,您可以定义定义名称的上下文。本质上,命名空间定义了一个作用域。
定义命名空间
命名空间的定义以关键字 namespace 开头,后跟命名空间名称,如下所示 -
namespace namespace_name { // 代码声明 }
要调用启用命名空间的函数或变量版本,请在前面添加 (::) 命名空间名称,如下所示 -
name::code; // 代码可以是变量或函数。
让我们看看命名空间如何作用于包括变量和函数在内的实体 -
#include <iostream> using namespace std; // 名字空间 namespace first_space { void func() { cout << "Inside first_space" << endl; } } // 第二个命名空间 namespace second_space { void func() { cout << "Inside second_space" << endl; } } int main () { // 从第一个命名空间调用函数。 first_space::func(); // 从第二个命名空间调用函数。 second_space::func(); return 0; }
如果我们编译并运行上述代码,将产生以下结果 -
Inside first_space Inside second_space
using 指令
您还可以使用 using namespace 指令避免在命名空间前添加前缀。该指令告知编译器后续代码正在使用指定命名空间中的名称。因此,以下代码隐含了该命名空间 -
#include <iostream> using namespace std; // 第一个命名空间 namespace first_space { void func() { cout << "Inside first_space" << endl; } } // 第二个命名空间 namespace second_space { void func() { cout << "Inside second_space" << endl; } } using namespace first_space; int main () { // 这从名字空间调用函数。 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 指令处到该指令所在作用域的末尾均可见。在外部作用域中定义的同名实体将被隐藏。
不连续的命名空间
命名空间可以分为多个部分定义,因此命名空间由其单独定义的部分的总和组成。命名空间的各个部分可以分布在多个文件中。
因此,如果命名空间的某个部分需要另一个文件中定义的名称,则仍然必须声明该名称。编写以下命名空间定义可以定义新的命名空间或向现有命名空间添加新元素 −
namespace namespace_name { // 代码声明 }
嵌套命名空间
命名空间可以嵌套,您可以在一个命名空间内定义另一个命名空间,如下所示 -
namespace namespace_name1 { // 代码声明 namespace namespace_name2 { // 代码声明 } }
您可以使用解析运算符访问嵌套命名空间的成员,如下所示 -
// 访问 namespace_name2 的成员 using namespace namespace_name1::namespace_name2; // 访问 namespace:name1 的成员 using namespace namespace_name1;
如果在上述语句中使用了 namespace_name1,则 namespace_name2 中的元素将在作用域内可用,如下所示 -
#include <iostream> using namespace std; // 第一个名称空间 namespace first_space { void func() { cout << "Inside first_space" << endl; } // 第二个命名空间 namespace second_space { void func() { cout << "Inside second_space" << endl; } } } using namespace first_space::second_space; int main () { // 这会从第二个命名空间调用函数。 func(); return 0; }
如果我们编译并运行上述代码,将产生以下结果 -
Inside second_space