C++命名空间详解:概念、创建与使用方法
C++命名空间详解:概念、创建与使用方法
命名空间是C++中一个重要的概念,它可以帮助我们更好地组织代码,避免命名冲突。本文将从基础到进阶,逐步深入地介绍命名空间的概念、创建方法、使用方式以及一些注意事项。
一、什么是命名空间
在C++的学习中,命名空间是一个基础的内容。我们先观察下方代码:
如果你之前经历过C语言的学习,你就会注意到这段代码的两个不同,首先是代码所用头文件的不同,对于scanf和printf两个函数,C语言标准库中采用的是<stdio.h>这个函数库,但在C++中则在
在C语言中,我们常遇到定义变量名时与函数库中定义的变量名重复而报错,因此不得不采用新的命名方式与之区分。但这会给我们造成很多不必要的麻烦,并且有时候库函数中的同名变量我们根本就用不到,C++在设计时为了解决这一问题,加入了命名空间这一语法,也就是上述代码第三行中提到的
namespace std;
其中std为一个指定命名空间的名字,可以自由定义,只要不与库中变量重名就可以。
二、命名空间的使用
1.命名空间的创建
我们可以用如下方式定义一个命名空间:
namespace SpaceName
{
int a = 0;
double b = 1.52;
struct c{
int elem1 = 1;
...
};
char ...;
...
}
在命名空间中,我们既可以定义各种类型的变量,也可以定义结构体、枚举等自定义类型,还可以定义函数、宏,甚至还可以包含头文件或者嵌套新的命名空间。
但是要注意的是,命名空间中只能设置声明,不能添加其他的代码段,如 for 循环等。
2.命名空间的使用
当我们创建好了一个命名空间,要使用命名空间中的变量时,若没有特殊声明,编译器会将使用的变量视为未定义变量,从而出现报错。
那么我们要如何使用命名空间呢?
1.在变量前加上命名空间名
每当我们需要用到命名空间中定义的变量的时候,我们要在变量名前额外加上一个声明,指出是使用哪一个命名空间中的变量,命名空间名之后加上作用于限定符 :: ,表示从该命名空间中取用元素。
对于命名空间嵌套的情况,与之类似,只需要在在命名空间名前加一个包含它的命名空间名就行,多重嵌套也类似。
2.将命名空间展开
当我们要大量使用命名空间里的变量时,每一次都要在变量前面加一个声明,这十分的繁琐,工作量太大。这时我们就可以对命名空间进行展开,用 using namespace 加上对应的命名空间名,这样就可以直接使用命名空间中的变量,不需要每一次都加上声明。
其原理是给编译器编译时开辟了一个渠道,使其在全局域中寻找变量时能直接进入展开的命名空间进行搜索,因此不用再在变量或函数等元素前加上指定命名空间声明。另外,若局部域中定义了与命名空间中同名变量,则编译过程中就会优先使用在局部域中的值,然后是展开的命名空间域中的值,不会引起冲突。但是若在全局中定义了域与展开的命名空间域中同名的变量,编译器就会报错,因为编译器在全局域中搜索时,由于已经开辟了进入命名空间搜索的途径,与全局域中变量属于同一等级,所以编译器也会进入命名空间进行搜索,这会导致编译器搜索到两个同名变量,无法确定取用哪一个。
但是,若在打印时指定一个确定变量,就不会产生冲突,因为编译器在确定值时不会产生歧义。
另外,如果同时展开多个命名空间,出现有两个或多个命名空间中有同名变量的情况,则在编译过程中需要取用该同名元素时就会引起冲突,出现报错。
三、注
- 命名空间是定义在全局域的,因此其中的变量都存储在静态区。
- 命名空间的实质就是用一个声明将定义在其内部的变量、函数等直接装起来,而不在全局域中,所以使用变量时不限定命名空间域无法使用,编译时编译器只会看局部域和全局域,而不能直接在命名空间域中寻找,需要程序员在变量前加上命名空间名,编译器才能通过指定的路径进入命名空间访问对应元素。而命名空间展开就是给编译器在全局域中访问时自由进入命名空间寻找元素的路径,但是要注意此时的命名空间与全局域还是不同作用域,并不等于将命名空间与全局域合并。
- 在C++中,为了防止程序员声明与标准库同名而发生冲突,C++设计者将所有官方的库函数都放在了名为 std 的命名空间中,所以可以知道为什么在第一张图的代码中可以看到 using namespace std; 一句。