C++ 语言命名空间 (namespace) 和 using 声明 (using declaration)

蔚落 2022-09-03 01:26 239阅读 0赞

C++ 语言命名空间 (namespace) 和 using 声明 (using declaration)

命名空间可作为附加信息来区分不同库中相同名称的函数、类、变量等。命名空间定义了上下文,就是定义了一个范围。一个文件夹 (目录) 中可以包含多个文件夹,每个文件夹中不能有相同的文件名,但不同文件夹中的文件可以重名。

1. 命名空间

命名空间的定义使用关键字 namespace,后跟命名空间的名称。

  1. namespace namespace_name {
  2. // 代码声明
  3. }

为了调用带有命名空间的函数或变量,需要在前面加上命名空间的名称。

  1. namespace_name::yongqiang; // yongqiang 可以是变量或函数
  2. //============================================================================
  3. // Name : Yongqiang Cheng
  4. // Author : Yongqiang Cheng
  5. // Version : Version 1.0.0
  6. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  7. // Description : Hello World in C++, Ansi-style
  8. //============================================================================
  9. #include <iostream>
  10. // 第一个命名空间
  11. namespace first_space {
  12. void yongqiang() {
  13. std::cout << "Inside first_space" << std::endl;
  14. }
  15. }
  16. // 第二个命名空间
  17. namespace second_space {
  18. void yongqiang() {
  19. std::cout << "Inside second_space" << std::endl;
  20. }
  21. }
  22. int main()
  23. {
  24. // 调用第一个命名空间中的函数
  25. first_space::yongqiang();
  26. // 调用第二个命名空间中的函数
  27. second_space::yongqiang();
  28. return 0;
  29. }
  30. Inside first_space
  31. Inside second_space
  32. 请按任意键继续. . .

2. 命名空间的 using 声明 (using declaration)

using namespace 指令会告诉编译器,后续的代码将使用指定的命名空间中的名称。

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. using namespace std;
  10. // 第一个命名空间
  11. namespace first_space {
  12. void yongqiang() {
  13. cout << "Inside first_space" << endl;
  14. }
  15. }
  16. // 第二个命名空间
  17. namespace second_space {
  18. void yongqiang() {
  19. cout << "Inside second_space" << endl;
  20. }
  21. }
  22. using namespace first_space;
  23. int main()
  24. {
  25. // 调用第一个命名空间中的函数
  26. first_space::yongqiang();
  27. // 调用第二个命名空间中的函数
  28. second_space::yongqiang();
  29. // 调用第一个命名空间中的函数
  30. yongqiang();
  31. return 0;
  32. }
  33. Inside first_space
  34. Inside second_space
  35. Inside first_space
  36. 请按任意键继续. . .

using 指令用来指定命名空间中的特定项目,

  1. using std::cout;

使用 std 命名空间中的 cout 部分,在使用 cout 时就可以不用加上命名空间名称作为前缀,但是 std 命名空间中的其他项目仍然需要加上命名空间名称作为前缀。

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. using std::cout;
  10. int main()
  11. {
  12. cout << "yongqiang cheng!" << std::endl;
  13. return 0;
  14. }
  15. yongqiang cheng!
  16. 请按任意键继续. . .

using 指令引入的名称遵循正常的范围规则。名称从使用 using 指令开始是可见的,直到该范围结束。在范围以外定义的同名实体是隐藏的。

std::cin 表示从标准输入中读取内容,std 为命名空间。作用域操作符 :: 表示编译器应从操作符左侧名字所示的作用域中寻找右侧那个名字,std::cin 就是要使用命名空间 std 中的名字 cin

using 声明具有如下的形式:

  1. using namespace::name;

一旦声明了上述语句,就可以直接访问命名空间中的名字。

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. /* using 声明,当我们使用名字 cin 时,从命名空间 std 中获取。 */
  10. using std::cin;
  11. int main()
  12. {
  13. int val;
  14. /* cin 和 std::cin 含义相同。 */
  15. cin >> val;
  16. /* 没有对应的 using 声明,必须使用完整的名字,显式地从 std 中使用。 */
  17. std::cout << val << std::endl;
  18. return 0;
  19. }
  20. 9
  21. 9
  22. 请按任意键继续. . .

每个名字都需要独立的 using 声明,每个 using 声明引入命名空间中的一个成员。

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. using std::cin;
  10. using std::cout; using std::endl;
  11. int main()
  12. {
  13. cout << "Enter two numbers: " << endl;
  14. int vl, v2;
  15. cin >> vl >> v2;
  16. cout << "The sum of " << vl << " and " << v2 << " is " << vl + v2 << endl;
  17. return 0;
  18. }
  19. Enter two numbers:
  20. 5 2
  21. The sum of 5 and 2 is 7
  22. 请按任意键继续. . .

在上述程序中,一开始就有对 cincoutendl 的 using 声明,这意味着我们不用再添加 std:: 形式的前缀就能直接使用它们。C++ 语言的形式比较自由,因此既可以一行只放一条 using 声明语句,也可以一行放上多条。不过要注意,用到的每个名字都必须有自己的声明语句,而且每句话都得以分号结束。

头文件不应包含 using 声明
位于头文件的代码一般来说不应该使用 using 声明。这是因为头文件的内容会拷贝到所有引用它的文件中去,如果头文件里有某个 using 声明,那么每个使用了该头文件的文件就都会有这个声明。对于某些程序来说,由于不经意间包含了一些名字,反而可能产生始料未及的名字冲突。

3. 不连续的命名空间

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

如果命名空间中的某个组成部分需要请求定义在另一个文件中的名称,则仍然需要声明该名称。下面的命名空间定义可以是定义一个新的命名空间,也可以是为已有的命名空间增加新的元素:

  1. namespace namespace_name {
  2. // 代码声明
  3. }

4. 嵌套的命名空间

命名空间可以嵌套,您可以在一个命名空间中定义另一个命名空间。

  1. namespace namespace_name1 {
  2. // 代码声明
  3. namespace namespace_name2 {
  4. // 代码声明
  5. }
  6. }

使用 :: 运算符来访问嵌套的命名空间中的成员。

  1. // 访问 namespace_name2 中的成员
  2. using namespace namespace_name1::namespace_name2;
  3. // 访问 namespace:name1 中的成员
  4. using namespace namespace_name1;

如果使用的是 namespace_name1,那么在该范围内 namespace_name2 中的元素也是可用的。

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. using namespace std;
  10. // 第一个命名空间
  11. namespace first_space {
  12. void yongqiang() {
  13. cout << "Inside first_space" << endl;
  14. }
  15. // 第二个命名空间
  16. namespace second_space {
  17. void yongqiang() {
  18. cout << "Inside second_space" << endl;
  19. }
  20. }
  21. }
  22. using namespace first_space::second_space;
  23. int main()
  24. {
  25. // 调用第一个命名空间中的函数
  26. first_space::yongqiang();
  27. // 调用第二个命名空间中的函数
  28. first_space::second_space::yongqiang();
  29. // 调用第二个命名空间中的函数
  30. yongqiang();
  31. return 0;
  32. }
  33. Inside first_space
  34. Inside second_space
  35. Inside second_space
  36. 请按任意键继续. . .

5. 命名空间内变量、函数、全局变量的作用域

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. // 第一个命名空间
  10. namespace first_space {
  11. int num = 99;
  12. // 第二个命名空间
  13. namespace second_space {
  14. int num = 11;
  15. }
  16. }
  17. // 全局变量
  18. int num = 55;
  19. int main()
  20. {
  21. std::cout << "first_space::num = " << first_space::num << std::endl;
  22. std::cout << "first_space::second_space::num = " << first_space::second_space::num << std::endl;
  23. std::cout << "num = " << num << std::endl;
  24. std::cout << "::num = " << ::num << std::endl;
  25. int num = 77;
  26. std::cout << "num = " << num << std::endl;
  27. std::cout << "::num = " << ::num << std::endl;
  28. return 0;
  29. }

全局变量 num 表达为 ::num,当有同名的局部变量时来区别两者。

  1. first_space::num = 99
  2. first_space::second_space::num = 11
  3. num = 55
  4. ::num = 55
  5. num = 77
  6. ::num = 55
  7. 请按任意键继续. . .
  8. //============================================================================
  9. // Name : Yongqiang Cheng
  10. // Author : Yongqiang Cheng
  11. // Version : Version 1.0.0
  12. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  13. // Description : Hello World in C++, Ansi-style
  14. //============================================================================
  15. #include <iostream>
  16. // 第一个命名空间
  17. namespace first_space {
  18. int num = 99;
  19. void yongqiang() {
  20. std::cout << "Inside first_space" << std::endl;
  21. std::cout << "num = " << num << std::endl;
  22. }
  23. // 第二个命名空间
  24. namespace second_space {
  25. int num = 11;
  26. void yongqiang() {
  27. std::cout << "Inside first_space" << std::endl;
  28. std::cout << "num = " << num << std::endl;
  29. }
  30. }
  31. }
  32. int main()
  33. {
  34. std::cout << "first_space::num = " << first_space::num << std::endl;
  35. std::cout << "first_space::second_space::num = " << first_space::second_space::num << std::endl;
  36. std::cout << "num = " << num << std::endl;
  37. std::cout << "::num = " << ::num << std::endl;
  38. return 0;
  39. }
  40. 1>------ Build started: Project: hash_table, Configuration: Debug Win32 ------
  41. 1> yongqiang.cpp
  42. 1>d:\visual_studio_workspace\hash_table\hash_table\yongqiang.cpp(35): error C2065: 'num': undeclared identifier
  43. 1>d:\visual_studio_workspace\hash_table\hash_table\yongqiang.cpp(36): error C2039: 'num': is not a member of '`global namespace''
  44. 1>d:\visual_studio_workspace\hash_table\hash_table\yongqiang.cpp(36): error C2065: 'num': undeclared identifier
  45. ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

using 来告诉编译器用到的是哪个命名空间内的内容。在 main() 中加 using namespace first_space; 或者 using namespace first_space::second_space;。但是不能同时使用,因为这样也会导致编译出错,编译器不知道要去使用哪个命名空间的变量和函数。

5.1 using namespace first_space;

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. // 第一个命名空间
  10. namespace first_space {
  11. int num = 99;
  12. void yongqiang() {
  13. std::cout << "Inside first_space" << std::endl;
  14. std::cout << "num = " << num << std::endl;
  15. }
  16. // 第二个命名空间
  17. namespace second_space {
  18. int num = 11;
  19. void yongqiang() {
  20. std::cout << "Inside first_space" << std::endl;
  21. std::cout << "num = " << num << std::endl;
  22. }
  23. }
  24. }
  25. using namespace first_space;
  26. int main()
  27. {
  28. std::cout << "first_space::num = " << first_space::num << std::endl;
  29. std::cout << "first_space::second_space::num = " << first_space::second_space::num << std::endl;
  30. std::cout << "num = " << num << std::endl;
  31. std::cout << "::num = " << ::num << std::endl;
  32. return 0;
  33. }
  34. first_space::num = 99
  35. first_space::second_space::num = 11
  36. num = 99
  37. ::num = 99
  38. 请按任意键继续. . .

5.2 using namespace first_space::second_space;

  1. //============================================================================
  2. // Name : Yongqiang Cheng
  3. // Author : Yongqiang Cheng
  4. // Version : Version 1.0.0
  5. // Copyright : Copyright (c) 2020 Yongqiang Cheng
  6. // Description : Hello World in C++, Ansi-style
  7. //============================================================================
  8. #include <iostream>
  9. // 第一个命名空间
  10. namespace first_space {
  11. int num = 99;
  12. void yongqiang() {
  13. std::cout << "Inside first_space" << std::endl;
  14. std::cout << "num = " << num << std::endl;
  15. }
  16. // 第二个命名空间
  17. namespace second_space {
  18. int num = 11;
  19. void yongqiang() {
  20. std::cout << "Inside first_space" << std::endl;
  21. std::cout << "num = " << num << std::endl;
  22. }
  23. }
  24. }
  25. using namespace first_space::second_space;
  26. int main()
  27. {
  28. std::cout << "first_space::num = " << first_space::num << std::endl;
  29. std::cout << "first_space::second_space::num = " << first_space::second_space::num << std::endl;
  30. std::cout << "num = " << num << std::endl;
  31. std::cout << "::num = " << ::num << std::endl;
  32. return 0;
  33. }
  34. first_space::num = 99
  35. first_space::second_space::num = 11
  36. num = 11
  37. ::num = 11
  38. 请按任意键继续. . .

References

https://www.runoob.com/cplusplus/cpp-tutorial.html
(美) Stanley B. Lippman, (美) Josée Lajoie, (美) Barbara E. Moo 著, 王刚, 杨巨峰 译. C++ Primer 中文版[M]. 第 5 版. 电子工业出版社, 2013.
https://www.informit.com/store/c-plus-plus-primer-9780321714114

发表评论

表情:
评论列表 (有 0 条评论,239人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++】namespace 命名空间

    名称空间 两个术语: 声明区域:声明区域是可以在其中进行声明的区域。 潜在作用域:变量的潜在作用域从声明点开始,到其声明区域的结尾。因此潜在作用域比声明区域

    相关 C++ | 命名空间_namespace

    C语言中是不存在命名空间的概念的,因为整个C语言工程就是一个大型的命名空间。当工程规模小时,不会产生大问题;但是一旦工程的规模大,会用到大量的动态库,尤其是第三方开发的动态库时

    相关 c++ using namespace std;

    一、先说<iostream.h>和<iostream>这两个被\include的预处理命令,它们是不一样的,它们其实是2个文件,两个文件的内容也是不一样的,.h的文件新的C++