大家在初学C++时,经常会看到using namespace std; 这段语句,下面对其做个简单的解释。
命名空间的由来
这个其实是C++对C语言的命名进行了一个优化。在C语言中,一个项目中命名是不能重复的,这容易对大型项目或者团队开发中产生很大影响。团队开发中一个人负责一块功能实现,当引入其他人的头文件或代码时,经常会发生重复命名,列如A在自己的负责的代码中申明了一个max变量,而B也命名了一个max变量,当B引用A代码时就会出现重复命名的问题。
所以C++的开发人员就引入了一个命名空间的概念,将一个个命名放入一个个命名空间,避免与其他所冲突。这大大便利了大型项目和团队的开发。
命名空间的用法
1、命名规则/语法:
namespace + 命名空间名
{
命名 // 可以是变量/函数/类型/结构体
}
例如:
namespace A //自定义命名空间A
{
int a; //命名空间A中自定义的变量a
int Add(int a, int b) //命名空间A中自定义的函数Add
{
return a + b;
}
struct Node //命名空间A中自定义的结构体Node
{
int val;
struct Node* next;
};
}
这样便算是成功在A命名空间中申明了一个变量a
并且自定义命名空间支持嵌套结构
例如:
namespace A
{
namespace B
{
int a = 0; //命名空间A::B中自定义的变量a
}
}
2、使用命名空间
(1)指定命名空间访问
指定命名空间访问语法为:命名空间名 + :: + 命名空间中所要访问的名称(::为作用域运算符)
如下代码所示:
#include <iostream>
namespace A //自定义命名空间A
{
int a = 0; //命名空间中自定义的变量a
int Add(int a, int b) //命名空间A中自定义的函数Add
{
return a + b;
}
struct Node //命名空间A中自定义的结构体Node
{
int val;
struct Node* next;
};
}
int main() {
A::a = 10; //指明命名空间访问(命名空间名 + :: + 命名空间中所要访问的名称)
struct A::Node* p1;
std::cout << A::a << std::endl; //std是cout,endl的命名空间名
std::cout << A::Add(2, 6) << std::endl;
return 0;
}
输出结果为:
10
8
如果自定义命名空间嵌套多级,便从外向里层级访问如
namespace A
{
namespace B
{
int a = 0; //命名空间A::B中自定义的变量a
}
}
访问变量a 得通过A::B::a , 直接 B::a是错误的。
但可以搭配全局展开和常用展开进行层级访问
(2)全局展开
全局展开语法为using namespace + 自定义空间名字;
using namespace std; 大家常见的这段语句便是全局展开
下面两端语句便是全局展开和指定命名空间访问的区别
同样是输出hello world
using namespace std;
cout << "hello world" << endl;
std::cout << "hello world" << std::endl; //未全局展开
全局展开在我们日常写代码的时候可以降低繁琐,适用于日常练习,小的程序,不太会出现命名重复冲突。
但是一般并不建议使用全局展开,不利于团队协作开发和开发大项目。
(3)常用展开
常用展开语法为using + 自定义空间名字 + 空间中的变量
有时我们经常使用一个变量一个名称的时候,我们会采用常用展开,省去一级一级的指定访问,降低繁琐。
比如输出语句便十分常用我们可以将其进行常用展开。
代码如下:
#include <iostream>
using std::cout; //输出
int main()
{
cout << "hello world" << std::endl;
return 0;
}
命名空间重复定义
其分为两种情况:
1、引入头文件中namespace所自定义空间名字相同时,命名空间中成员名称无重复,那么他们会合并为一个命名空间,编译通过
2、引入头文件中namespace所自定义空间名字相同时,命名空间中成员名称有重复,那么程序会在链接时报错。因为连接器会检测到重复定义的变量
结论:重复定义只针对有内存操作的变量等相关定义,命名空间定义没有内存相关操作,所以不存在重复定义问题。
注意事项
- namespace只能定义在全局,当然他还可以嵌套定义。
- 项目工程中多文件中定义的同名namespace会认为是同一个namespace,不会冲突。
- C++标准库都放在一个叫std(standard)的命名空间中。
希望这篇博客能对大家有所帮助。