名称空间与作用域
名称空间简介
以前稍微讲过,这次再讲多一点
实际上就是一个由程序设计者命名的内存区域,
程序设计者可以根据需要指定一些有名字的空间域,
把一些全局实体分别放在各个命名空间中,
从而与其他全局实体分隔开来。
定义一个名称空间
//namespace 是一个关键字
namespace name //指定name的命名
{
...;
可以放变量;
可以放函数;
。。。;
}
//后面不用加分号
使用名称空间
假设我定义了这样一个名称空间
namespace mine
{
int x;
int y;
double b;
void swap(int & a, int & b);
}
我可以这样使用它
using namespace mine;
这条语句使名称空间里的所有名字能够直接使用
(即能够使用非限定名)
比如直接调用swap函数
swap(x, y);
我也可以这样使用
using mine::swap;
这条语句只使名称空间里的swap函数名能够直接使用
而其他的成员依旧不能直接使用
如果没有using语句
无论我们用mine名称空间里的哪个成员
都需要加上作用域解析运算符来调用
(即只能使用限定名)
比如:这样调用
mine::x = 3;
mine::y = 5;
mine::swap(mine::x, mine::y);
为什么需要名称空间呢?
先弄清楚作用域的层次体系
比较熟知的应该有3个层次的作用域
1. 文件作用域
2. 函数作用域
3. 代码块作用域
这里,作用域的作用是
让某一个变量或函数名只在某一个区域可见
名字冲突的产生
作用域也就代表了某个变量或者函数的可见范围
如果说在这个范围中
出现了相同的名字
名字冲突从而产生
为什么名称空间能够改善名字冲突
首先,我们以写项目为例
写一个项目,可能需要很多的文件同时编译
同时,我们还可能需要使用第三方的库
在使用第三方库的时候,我们通常的做法是
包含一个头文件
#include " ***.h "
这个时候,情况是这样的
我为了实现某个功能
我需要使用这个库的某个函数
于是,我直接把整个库给include了
然后,为了实现其他的功能
我还include了其他的库
这里最大的问题是,
我们只使用这几个库中的一部分成员
如果说这几个库
我没有使用的成员没有仔细检查
我不知道他们会不会有重复的名字
在编译的时候就会各种出错
如果给每个库里的每个成员都放进一个不同的名称空间呢?
问题迎刃而解
因为每个成员的名字,在没有使用using的情况下,默认是
名称空间名::成员名
就不会产生冲突
全局名称空间污染
也许这个就是一个最明显的例子
在C中,凡是内置的函数或者内置的标识符
我们都不能够用
可是我哪里知道有哪些是内置的?
这个时候,如果自己随便改名字
造成了与全局的名称冲突
就造成了全局名称空间污染
在C++中,一个最明显的改动就是
using namespace std;
只有加了这一条语句
才可以使标准函数库里面的名字直接可用
不然全都需要使用作用域解析运算符
std:: cout
std::cin
std:: max
。。。。。。
C++中的作用域层次
- 文件作用域
- 函数作用域
- 代码块作用域
- 类作用域
而名称空间的作用,
就是能够让用户
自己定义作用域的名称
自己定义作用域所含成员
在C++作用域层次下创造更实用的作用域
匿名名称空间
也就是说,在定义一个名称空间时
我们可以忽略这个名称空间的名称
namespce
{
char c;
int i;
double d;
}
有什么用呢?
在匿名名称空间中
名称的作用域被限制在当前文件中
无法通过在另外的文件中使用extern声明来进行链接
也就是说这个例子里的
变量c,变量i, 变量d
只有在当前文件里可以使用
std名称空间
想提醒一下
所有标准库函数都在这个名称空间中
包括cout, cin
包括string类
包括strcmp函数和strcpy函数
等等……全都在这个名称空间中
(当然还有STL也在这个名称空间中)
今天累啊累啊,可能写的不太好……
还有很多东西想写的
又没想到怎么写比较好……
希望明天能做点补充
而且!明天开始写类!