【C++】命名空间namespace详解
一、命名空间的引入
C++
中,名称(name)
可以是符号常量、变量、宏、函数、结构体、枚举、类和对象等等。而在大型工程中,难免会有重名的现象,命名空间namespace
,就是C++
引入的一种解决名称冲突的机制
1.1 如何解决命名冲突
C语言中
C语言中是通过人为操作符号名称、限制符号的作用域和链接属性来完解决名称冲突的。比如:
- 同一个C文件中的全局变量/函数加一个统一的前缀
- 通过作用域的掩蔽规则来进行覆盖(在大文件中如果出错很难发现)
- C文件中的全局变量和函数都是
extern
链接属性,可以用static
将无需跨文件访问的全局变量和函数限制在内链接属性中
Cpp中
为实现命名空间机制,C++
中引入了namespace
关键字,定义格式为
namespace NAME
{/*符号定义*/
}
一个特定名称为NAME
的命名空间的一对大括号内部定义的符号均被限制在该命名空间内,在命名空间内部各符号可以直接相互引用,而跨命名空间相互引用时必须同时指定被引用符号的命名空间名称。从某种意义上来说,命名空间就类似于一种前缀,本质上而言,就相当于控制了符号的作用域和链接属性。
二、namespace
的使用
需要注意的是,命名空间不能定义在任何函数的内部,包括主函数,但是可以嵌套定义。
2.1 同一文件内常规使用namespace
namespace
有三种使用方法:
- 使用时对符号附带命名空间的名称
- 使用前对该符号进行声明,后面直接使用该符号
- 使用前声明整个命名空间,后面对直接使用该命名空间中的任何符号
#include <iostream>namespace NM1
{int a = 1;int b = 2;
}void func1(void);using namespace std;//声明std命名空间,后面可以使用该命名空间中的任何符号,如cout、endl...
using NM1::a; //声明命名空间NM1中的a,后面可以直接对a进行使用int main(void)
{cout << "the value of a is: " << a << endl;cout << "the value of b is: " ;cout << NM1::b;//使用变量时直接附带命名空间cout << endl;return 0;
}
2.2 命名空间内定义函数
我们可以在命名空间内直接定义函数,但是不能只声明不定义,否者链接时会出错
#include <iostream>namespace NM1
{using namespace std;void func1(void){cout << "Func1 in NM1" << endl;}void func2(void){func1();}
}using namespace NM1;int main(void)
{func1();func2();return 0;
}
这是合法的使用
如果我们只声明,而在默认命名空间(后文会阐述)中去定义,如下所示:
#include <iostream>namespace NM1
{void func1(void);
}using namespace NM1;int main(void)
{func1();return 0;
}void func1(void)
{std::cout << "Func1 in NM1" << std::endl;
}
则会出现链接错误,因为func1
在定义和声明时不再同一个作用域
2.3 嵌套使用命名空间
这个东西也很简单,如下测试代码
#include <iostream>namespace NEST1
{using namespace std;void func1(void){cout << "Func1 in NEST1" << endl;}namespace NEST2{void func2(void){cout << "Func2 in NEST1::NEST2" << endl;}}
}int main(void)
{NEST1::func1();NEST1::NEST2::func2();return 0;
}
2.4 跨文件使用namespace
建立相应的测试文件
touch external_test.cpp external_test.h main.cpp CMakeLists.txt
对应的内容如下:
external_test.h
中
#ifndef CPP_EXTERNAL_TEST_H_
#define CPP_EXTERNAL_TEST_H_namespace EX1
{void func(void);
}#endif
external_test.cpp
中
#include "external_test.h"
#include <iostream>namespace EX1
{ using namespace std;void func(void){cout << "Func in EX1" << endl;}
}
main.cpp
中
#include "external_test.h"using namespace EX1;int main(void)
{func();return 0;
}
测试结果如下,EX1
成功跨文件调用
在正规场合都是通过头文件的包含来进行namespace
的跨文件调用,有时也可以通过对命名空间内的符号进行extern
全局声明
建立相应的测试文件
touch external_test.cpp main.cpp CMakeLists.txt
相应内容如下:
extern_test.cpp
中:
#include <iostream>namespace EX1
{ using namespace std;void func(void){cout << "Func in EX1" << endl;}
}
main.cpp
中
namespace EX1
{ extern void func(void);
}using namespace EX1;int main(void)
{func();return 0;
}
三、一些特殊的命名空间
3.1 std命名空间
标准C++
库的所有的标识符(函数、类、模板等)是在一个名为std
的命名空间中定义的,std
是standard
(标准)的缩写,表示这是存放标准库的有关内容的命名空间。
3.2 默认命名空间
默认命名空间又叫全局命名空间,就是除了其他的命名空间之外的部分,比如说我们的主函数就是在默认命名空间中的,在其他命名空间引用默认命名空间中的符号的方法有两种:
- 直接使用
- 在符号前加
::
3.3 匿名命名空间
匿名命名空间就是没有名字的命名空间,定义如下:
namespace
{/*符号*/
}
匿名命名空间中的符号纯本空间内部使用,不能被外部引用,效果类似于全局变量和函数加static
,但是比C中的static
使用范围广
【C++】命名空间namespace详解相关推荐
- C/C++中命名空间(namespace)详解及其作用介绍
命名空间 (namespace) 可以帮助我们区分不同库中相同名称的函数, 类, 变量等. 使用了命名空间即定义了上下文. 命名空间就是定义了一个范围. 命名空间 为了解决 C++ 标准库中的标识符与 ...
- 【024】C++对C的扩展之命名空间namespace详解
C++对C的扩展 引言 一.面向对象编程概述 1.1.面向过程 1.2.面向对象 二.作用域运算符 :: (双冒号) 三.命名空间 namespace 3.1.命名空间使用语法 3.2.using声明 ...
- 【C++】命名空间(namespace)详解
一.为什么使用命名空间 考虑一种情况,当我们有两个同名的人,Zara,在同一个班里.当我们需要对它们进行区分我们必须使用一些额外的信息和它们的名字,比如这个区域,如果它们生活在不同的区域或者它们的母 ...
- k8s之Namespace详解
Namespace 隔离资源 默认情况下,kubernetes集群中的所有的Pod都是可以相互访问的.但是在实际中,可能不想让两个Pod之间进行互相的访问,那此时就可以将两个Pod划分到不同的name ...
- Docker 基础技术之 Linux namespace 详解
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. Docker ...
- Linux ns 5. IPC Namespace 详解
文章目录 1. 简介 2. 源码分析 2.1 copy_ipcs() 2.2 ipcget() 2.3 ipc_check_perms() 2.4 相关系统调用 参考文档: 1. 简介 进程间通讯的机 ...
- Linux ns 3. Mnt Namespace 详解
1. 文件系统层次化 对 Linux 系统来说一切皆文件,Linux 使用树形的层次化结构来管理所有的文件对象. 完整的Linux文件系统,是由多种设备.多种文件系统组成的一个混合的树形结构.我们首先 ...
- 【转】C#中的命名空间namespace全解
.NET Framework 类库提供下列命名空间: [Microsoft] Microsoft.CSharp 包含支持用 C# 语言进行编译和代码生成的类. Microsoft.JScript 包含 ...
- django url 中的namespace详解
[引子] django是一个比较全能的web框架,比如它实现了自己的orm模型来对接不同的数据库.并提供了方便的数据接口:django牛逼的地方 还有许多,如他实现了自己的模板语言,这样我们就能方便的 ...
最新文章
- 今天意外和身份证结缘
- 图文详解 Kubernetes,刺激…
- 命令行实现SMTP和IMAP
- Builder 模式
- GPRS底层API(转)
- pythonsuper多重继承_Python super()函数使用及多重继承
- 数据库笔记01:SQL Server系统概述
- mysql如何通过数据库修改root_MySQL数据库之MySQL——修改root密码的4种方法(以windows为例)...
- 明基电通董事长李焜耀
- 存储系统的实现-探析存储的机制和原理
- C# 最简单的全局键盘鼠标钩子
- scrum敏捷开发项目管理工具必备
- App Store 受欢迎榜单(美国区)-分析出未来方向
- [ActiveForm] -- ActiveForm::begin表单用法
- 原型工具Axure6.5的使用
- Arduino基础项目五:制作彩色LED灯
- 助力CP扬帆出海,华为HiGame邀全国开发者共赢拉美市场
- 线程死锁 导致 服务器cpu负载过高
- 手游联运系统隐藏福利大揭秘
- 南方CASS格式DWG的读取
热门文章
- NetCore 框架下ABP多数据库切换搭建
- Git 配置用户名、密码
- 如何描述业务流程体系
- 计算机组成原理邓蕾蕾,_计算机组成原理_课程立体化教学模式的研究与实践.pdf...
- PTA 1042 字符统计 (c语言)
- 乐蒙网-鸿蒙不再属于华为,工信部正式接手
- shell字段拼接日期_通过shell脚本获取日期,并赋给变量(转)
- linux adc检测,Linuxatsadc输入文件如何检查漏洞?
- 打卡-2023-4-1
- JavaScript编写的胸罩罩杯尺寸计算器