Featured image of post 命名空间

命名空间

命名空间

概念

本质:是一个自定义作用域

为什么要用命名空间?

为了解决引入大量库时,导致全局符号的冲突问题。

最基本作用:给不同的库和模块拥有自己独特的作用域

定义与使用

定义一个名字空间,实际上就是定义一个作用域,在名字空间中可以定义变量、函数等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
namespace ns
{
    //在ns中定义变量
    int a=1;
    
    //在ns中定义函数
    void printf()
    {
        std::cout << "命名空间ns中的变量a = " << a << std::endl;
    }
    
}

在ns中定义的a,与函数printf的实际名字为 ns::a和ns::printf

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
int main()
{
    // 方式1:使用 作用域解析符:: 访问命名空间中的成员
    std::cout << "直接访问:ns::a = " << ns::a << std::endl;
    
    // 调用命名空间中的函数
    ns::print();

    // 方式2:使用using声明,简化访问(无需重复写ns::)
    using namespace ns;
    std::cout << "using后直接访问:a = " << a << std::endl;
    print();

    return 0;
}

操作符::用法

1
2
名字空间::某符号
::某符号

::双冒号操作符,称为作用域引用符,双冒号前面必须是一个作用域

重要的作用:

  1. 解决命名冲突,明确指定使用哪个空间的变量

  2. 解决全局变量和局部变量重名的问题,直接写变量名访问局部,加**::**访问全局。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
int a = 666; 		//全局变量

int main() {
    int a = 888; 	//局部变量
    
    // 不加 :: 优先访问局部变量
    std::cout << a << std::endl; // 输出 888
    
    // 加 :: 强制访问全局变量
    std::cout << ::a << std::endl; // 输出 666
    
    return 0;
}

using语句

可以使用using语句实现导入名字空间

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include "ns.h"
#include <iostream>
using namespace std;
using namespace ns; 	  // 导入整个ns命名空间

int main() {
    cout << a << endl;    // 直接使用ns::a
    cout << f(8) << endl; // 直接使用ns::f()
    return 0;
}
1
2
3
4
5
6
//一:导入整个名字空间
using namespace ns;

//二:导入名字空间中指定的符号
using ns::a;
using ns::f;

如果使用某个命名空间时,仅使用到少量符号的话,如果导入整个名字空间,会导致大量未被使用的符号,会造成冲突,会造成名字空间污染

进阶

C++ 支持嵌套定义命名空间,也就是在一个命名空间内部再定义另一个命名空间。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#include "ns.h"

namespace ns {
    int a = 1; // 外层变量定义

    namespace nested_ns {
        int a = 2; // 内层变量定义
        int x = 100; // 内层变量定义
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#ifndef NS_H
#define NS_H

namespace ns {
    extern int a; // 外层变量声明

    namespace nested_ns {
        extern int a; // 内层变量声明
        extern int x; // 内层变量声明
    }
}

#endif

扩展性

当程序在多处定义了相同的名字空间时,它们将会融合成一个统一的作用域

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <iostream>
#include "ns.h"

// 扩展命名空间ns,新增变量b
namespace ns {
    int b = 666;
}

using namespace std;
using namespace ns;

int main(void) {
    cout << a << endl;  // 输出1
    cout << b << endl;  // 输出666
    return 0;
}

全局作用域

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
using namespace std;

// 全局变量
int global = 100;

int main()
{
    // 局部同名变量
    int global = 200;

    // 1. 直接访问:优先局部,输出200
    cout << global << endl;

    // 2. 加::访问:强制全局,输出100
    cout << ::global << endl;

    return 0;
}

全局作用域的名字空间是匿名的,引用全局作用域符号只需加 :: 即可。

最后更新于 2026-04-08 22:52