• C++名称空间


    名称空间是C++为了防止写程序时命名发送冲突而设计出来的,其实和文件夹类似,不同名称空间下的名称可以相同。
    接触过C++的人都应该对using namespace std很熟悉,这就是大家最常见的名称空间应用,叫做using编译指令,其中std是一个名称空间的名字。

    C++提供了两种机制来简化对名称空间中名称的使用:

    1. using声明(例如:using std::cout)
    2. using编译指令(例如:using namespace std)

    先我们来了解声明是名称空间,看代码

    #include <iostream>
    
    namespace nsp {
        int a = 0;
        void hello()
        {
            std::cout << "Hello!" << std::endl;
        }
    }
    
    int main()
    {
        std::cout << nsp::a << std::endl;
        nsp::hello();
    }
    

    代码中定义了名称空间 nsp,其中包含两个名称 a 和 hello,如果不使用 using 命令,那就只能用域解析运算符::来进行使用了。

    名称空间相当于将一些名称打包,然后给这个包取个名字,通过名称空间的名字和域解析运算符::就可以使用里面的名称了

    使用 using 声明,就是把里面的一个名称单独取出来使用,如:`using nsp::hello',要记住函数名称后面不能加括号
    使用 using 编译指令,就是把包给解开,使得所有名称都可以使用,如:'using namespace nsp'

    使用 using 指令后,名称的可用范围时从使用处起,到该作用域结束为止
    例如如果是在函数里用,就是从使用位置开始到函数结束的位置,在这个范围里可以直接使用释放出来的名称

    ::还可以用于访问被局部变量覆盖了的全局变量,如test.cpp中代码,其中::x表示的就是全局duoble型变量 x:

    #include <iostream>
    
    double x = 27.0;
    
    void test(int a)
    {
        int x = a;
        {
            using std::cout;
            char x = 'Q';
            cout <<  "最内层x = " << x << "
    "
                 <<  "全局::x = " << ::x << std::endl;
        }
        using std::endl;
        std::cout << "中间层x = " << x << '
    ' << endl;
    }
    

    下面是文件main.cpp的内容:

    extern void test(int x); // extern 可以省略,不省略的好处是可以明确指出这是在外部文件定义的函数
    
    namespace nsp {
        int a = 7;
    }
    
    int main()
    {
        using namespace nsp;
        test(a);    // a 为 7
        int a = 9;
        test(a);    // a 为 9
    }
    

    注意:使用 using 声明后,不可在同一级别的作用域里再次声明一样的名称,因为 using 声明也相当于声明,而 C++ 不允许在同一文件中重复声明,不过可以在不同级别的作用域里再次声明,一层花括号就是更深一层的作用域。不过 using 编译指令就没有这个限制了,你还是可以重复声明一次相同的名称。

    使用名称空间还需要注意:

    1. 名称空间可以嵌套,但不可以在代码块中,例如在函数中定义名称空间
    2. 同一名称空间可分布在不同的文件中,也可以在同一文件的不同位置
    3. 要使用名称空间中在其他文件里的变量或者函数,需要在本文件的名称空间中声明为外部变量,函数也一样

    如下面代码:

    // test.cpp
    #include <iostream>
    
    namespace nsp
    {
        double x = 27.0;
    
        void test(int a)
        {
            using namespace std;
            cout << a << endl;
        }
    }
    
    // main.cpp
    namespace nsp {
        int a = 7;
        extern double x;        // 必须加 extern 否则会报错
        extern void test(int);  // 可省略 extern
    }
    
    namespace nsp {
        int b = 8;
    }
    
    int main()
    {
        using namespace nsp;
        test(a);    // a 为 7
        test(b);    // b 为 8
        int a = 9;
        test(a);    // a 为 9
        test(x);    // x 为 27
    }
    

    下面是使用头文件的情况,一般在项目中都会把声明放到头文件中,然后再用同名称的.cpp文件来进行实现

    // test.h
    #ifndef TEST_H_INCLUDED
    #define TEST_H_INCLUDED
    
    namespace TEST
    {
        const double x = 27.0;  // 温馨提示:头文件中不要有变量
        void test(int);
    }
    
    #endif // TEST_H_INCLUDED
    
    
    // test.cpp
    #include <iostream>
    #include "test.h"
    
    namespace TEST
    {
        void test(int a)
        {
            using namespace std;
            cout << a << endl;
        }
    }
    
    // main.cpp
    #include "test.h"
    
    namespace  TEST {
        int a = 7;
    }
    
    namespace TEST {
        int b = 8;
    }
    
    int main()
    {
        using namespace TEST;
        test(a);    // a 为 7
        test(b);    // b 为 8
        int a = 9;
        test(a);    // a 为 9
        test(x);    // x 为 27
    }
    

    预编译指令#include "test.h"的作用其实就是将 test.h 文件中的内容替换掉这一行。

    我是七进制,一个被编程耽误的吉他手

  • 相关阅读:
    迭代器和生成器
    New test
    MySQL笔记整理
    Python基础数据类型
    Python基础
    Python入门知识
    Linux / MacOS 下Redis 安装、配置和连接
    NuGet的使用心得
    简单工厂模式和策略模式的区别与结合
    NuGet的使用和服务搭建
  • 原文地址:https://www.cnblogs.com/qijinzhi/p/cpp_namespace.html
Copyright © 2020-2023  润新知