欢迎访问我的博客首页。
1. 定义命名空间
定义命名空间的方式是 namespace 命名空间名{};,大括号后面的分号可有可无。下面定义一个名称为 n1 的命名空间。
namespace n1 {
};
2. 命名空间作用域
在命名空间内部可以直接访问该命名空间中的成员(子命名空间、变量、函数等),也可以加上该命名空间。
namespace n1 {
std::string x = "n1";
void print1() { std::cout << x << std::endl; }
void print2() { std::cout << n1::x << std::endl; }
};
命名空间由内向外匹配,且只匹配一次。比如,在 n1::n2 中访问 n2::x,会从 n1::n2 中找 x,找不到则报错,不会再向更外层查找命名空间 n2。
namespace n2 {
std::string x = "n2";
}
namespace n1 {
namespace n2 {
void print() { std::cout << n2::x << std::endl; }
}
}
在内层命名空间中可以直接访问外层命名空间,无须加任何命名空间名,比如,n1::n2::print() 可以输出 “n1”。在外层命名空间中不可直接访问内层命名空间,除非加上内层命名空间名,比如,n1::print1() 输出的是 “n1”,n1::print2() 输出的才是 “n12”。
namespace n1 {
std::string x = "n1";
namespace n2 {
void print() { std::cout << x << std::endl; }
std::string x = "n12";
}
void print1() { std::cout << x << std::endl; }
void print2() { std::cout << n2::x << std::endl; }
}
以上三个例子很好理解:把 namespace 换成 class,并把所有成员设置为 public static,则 namespace 和 class 成员的作用域完全一样。
3. 全局命名空间和变量
使用 ::命名空间名或变量名 访问全局定义的命名空间或变量,即访问最外层的命名空间或变量。
#include <iostream>
#include <string>
std::string x = "n0";
namespace n2 {
std::string x = "n2";
}
namespace n1 {
std::string x = "n1";
namespace n2 {
std::string x = "n12";
}
void print1() { std::cout << n2::x << std::endl; }
void print2() { std::cout << ::n2::x << std::endl; }
}
int main() {
std::cout << ::x << std::endl; // n0
std::cout << ::n1::x << std::endl; // n1
n1::print1(); // n12
n1::print2(); // n2
}
4. using 指示与声明
命名空间限制了其成员的作用范围,因此不同命名空间内名称相同的成员不会冲突。每次使用命名空间的成员都要加上命名空间的名字,可能会显得麻烦,因此可以使用 using 指示与声明。
using namespace std;
using std::cout;
上面两行代码分别是 using 指示和声明。使用 using 指示了命名空间 std,接下来就能在当前文件中不加 std:: 地使用其所有成员;使用 using 声明了命名空间的成员 std::cout,接下来只能在当前文件中不加 std:: 地使用其 cout 成员。
5. 参考
- C++ 命名空间,腾讯云,2021。