• 【C++】命名空间


    目录

    1 命名空间的引入

    2 命名空间的定义

    3 标准命名空间std

    头文件和std的关系

    4 命名空间的使用

    4.1 加命名空间名称及作用域限定符::

     4.2 使用using将命名空间中某个成员引入(最推荐)

    4.3 使用using namespace +命名空间名称

    5 总结


    1 命名空间的引入

    为了解决C语言中命名冲突问题,C++引入了命名空间:

    rand()函数包含在C语言头文件stdlib.h里,为了解决这个问题,可以这样做:

    2 命名空间的定义

    命名空间里可以放任意的变量、函数、结构体等等

    1. namespace space2
    2. {
    3. int a = 10;
    4. int add(int x, int y)
    5. {
    6. return x + y;
    7. }
    8. struct ListNode
    9. {
    10. struct ListNode* next;
    11. int val;
    12. };
    13. //...
    14. }

    命名空间的嵌套 

    1. namespace s3
    2. {
    3. int a = 10;
    4. namespace s4
    5. {
    6. int a = 20;
    7. }
    8. }

     命名空间s3和s4的变量a虽然同名,但并不会冲突!

    命名空间的合并

    1. #include
    2. namespace s3
    3. {
    4. int a = 10;
    5. }
    6. namespace s3
    7. {
    8. int b = 20;
    9. }
    10. int main()
    11. {
    12. std::cout << s3::b << std::endl;
    13. return 0;
    14. }

    上面的写法相当于:

    1. namespace s3
    2. {
    3. int a = 10;
    4. int b = 20;
    5. }

     std是C++的标准命名空间,::是作用域限定符,下面会详细介绍。

    3 标准命名空间std

    标准命名空间std是C++标准库中定义的命名空间,用于包含一系列标准库提供的类、函数和对象。它提供了一种组织和封装代码的机制,以避免命名冲突,并将相关的实体进行逻辑上的分组。在程序中使用std命名空间,可以方便地使用标准库中的函数、对象等。

    比如C++的标准输入cin输出cout,STL中的vector、sort、queue、stack等等都在std命名空间里。

    头文件和std的关系

    先来看一个C++输出hello world的程序:

    1. #include
    2. using namespace std;//标准命名空间std展开
    3. int main()
    4. {
    5. cout << "Hello World" << endl;
    6. return 0;
    7. }

    其中,iostream文件的包含以及标准命名空间std的展开都是缺一不可的,为什么呢?

    头文件和std命名空间的关系是,头文件中的内容被包含在std命名空间中。这意味着,如果一个头文件没有使用任何命名空间,那么其定义的所有符号都位于全局作用域;如果一个头文件使用了命名空间std,那么其定义的所有符号都位于std命名空间中。

    在C++标准库中,许多常用的函数、对象和类都被定义在std命名空间中,例如std::coutstd::vector等。因此,在使用这些函数、对象或类时,需要使用std::前缀来标识它们属于std命名空间。

    需要注意的是,虽然大部分编译器在实现时并没有严格遵循C++标准,对于原来C语言的头文件,即使按照C++的方式来使用,即#include 这种形式,那么符号可以位于命名空间std中,也可以位于全局范围中:

    如果我们将C++的cstdio头文件换成C语言的stdio.h头文件:

    原因是cstdio里的内容都被包含在std命名空间中,而stdio.h里的内容暴露在全局里!

    C++将C语言的头文件形式全部由.h结尾改成了以c开头,可能是为了和自己的一套规范相匹配,比如标准C++之前iostream的写法是iostream.h。

    不仅仅是头文件里定义的各种变量、函数等,我们自己定义的一系列东西如果暴露在全局里,就很容易造成命名冲突,因此我们在工作中使用C++语言进行工作时最好不要展开命名空间,那么接下来我们将继续介绍命名空间的使用以及作用域限定符。

    4 命名空间的使用

    1. namespace s3
    2. {
    3. int a = 10;
    4. namespace s4
    5. {
    6. int a = 20;
    7. }
    8. int add(int x, int y)
    9. {
    10. return x + y;
    11. }
    12. }

    我拿嵌套命名空间的例子向大家介绍命名空间的使用:

    4.1 加命名空间名称及作用域限定符::

    1. #include
    2. namespace s3
    3. {
    4. int a = 10;
    5. namespace s4
    6. {
    7. int a = 20;
    8. }
    9. int add(int x, int y)
    10. {
    11. return x + y;
    12. }
    13. }
    14. int main()
    15. {
    16. std::cout << "s3中的add(1,2)=" << s3::add(1,2) << std::endl;
    17. std::cout << "s3中的a=" << s3::a << std::endl;
    18. std::cout << "s4中的a=" << s3::s4::a << std::endl;
    19. return 0;
    20. }

    s4是包含在s3里的,所以要写成s3::s4

    如果我们要进行大量的输入输出,一句一句写std::cout岂不是太麻烦了?

     4.2 使用using将命名空间中某个成员引入(最推荐)

    为什么最推荐?

    ①减少代码量

    ②防止同名变量命名冲突

    1. #include
    2. using std::cout;
    3. using std::endl;
    4. namespace s3
    5. {
    6. int a = 10;
    7. namespace s4
    8. {
    9. int a = 20;
    10. }
    11. }
    12. using s3::a;
    13. using s3::s4;//err
    14. using s3::add;
    15. int main()
    16. {
    17. cout << "s3中的add(1,2)=" << add(1,2) << endl;//3
    18. cout << "s3中的a=" << a << endl;//10
    19. cout << "s4中的a=" << s3::s4::a << endl;//20
    20. return 0;
    21. }

    注意,作用域限定符不支持后面跟命名空间:

    4.3 使用using namespace +命名空间名称

    温馨提醒:平时我们自己写代码可以用,到公司上班了就最好不要写,和别人冲突了就不好了。

    1. using namespace std;//放在头文件前后都可以
    2. #include
    3. //using namespace s3;//放在s3前面就err
    4. namespace s3
    5. {
    6. int a = 10;
    7. namespace s4
    8. {
    9. int a = 20;
    10. }
    11. int add(int x, int y)
    12. {
    13. return x + y;
    14. }
    15. }
    16. using namespace s3;//ok
    17. int main()
    18. {
    19. cout << "hello world" << endl;
    20. cout << "s3中的a=" << add(1,2) << endl;
    21. cout << "s3中的a=" << a << endl;
    22. cout << "s4中的a=" << s4::a << endl;
    23. return 0;
    24. }

    使用using namespace+命名空间名称,就相当于少写了一层作用域限定符。

    需要注意的是,展开自己的命名空间和展开标准命名空间,自己的必须写在命名空间的定义下面std的既可以写在头文件上方也可以写在头文件下方

    5 总结

      本文介绍了C++的命名空间,C++的命名空间是为了解决C语言命名冲突的缺陷提出的,对于命名空间的使用,我推荐大家用4.2中的用法,这样有利于培养起优质的代码习惯!

      另外,今天是10/24,祝各位程序员节快乐!

  • 相关阅读:
    LeetCode 69.x的平方
    【C语言学习笔记---指针进阶02】
    Java I/O流概述
    python在循环中捕获异常后继续执行下一轮
    leetcode-240:搜索二维矩阵 II
    表哥月薪22k+,而我还在混日子……
    气死了,过五关,斩六将,结果被 HR 捅了一刀!!
    Seata分布式事务实现原理
    2-2、依赖注入以及特殊属性的赋值
    Spring实例化源码解析(一)
  • 原文地址:https://blog.csdn.net/weixin_73053512/article/details/134016174