参考C++ Primer plus第五版
第九章
名称空间(namespace)
可以解决什么问题:
很简单的例子,比如说在使用多个厂商的类库时,如果两个库都定义了名为List、Tree、Node这样的类,但定义的方式不兼容,我们可能希望使用一个库的List类,而使用另一个类库的Tree类,这就导致了名称的冲突,这种冲突被称为名称空间问题。
c++标准提供了名称空间工具,可以更好的控制名称的作用域。
先来看两个概念:声明区域、潜在作用域
声明区域
可以在其中进行声明的区域,例如可以在函数外声明全局变量,对于这种变量,其声明区域为其声明所在的文件,对于在函数中声明的变量,其声明区域为其声明所在的代码块。
潜在作用域
变量的潜在作用域从声明点开始到其声明区域的结尾。因此潜在作用域比声明区域小,这是由于变量必须定义后才能使用。
变量并非在其潜在作用域内的任何位置都是可见的
Header.h
#ifndef Header_h
#define Header_h
#endif /* Header_h */
namespace Jake {
double pail;
void fetch();
int pal;
struct Well{
};
}
Header2.h
#ifndef Header2_h
#define Header2_h
#endif /* Header2_h */
namespace Jill {
void bucket(double n)
{
};
double fetch;
int pal;
struct Hill{
};
}
main.cpp
#include <iostream>
#include <stdio.h>
#include "Header.h"
#include "Header2.h"
int main(int argc, const char * argv[]) {
Jill::fetch=234;
Jake::fetch();
return 0;
}
另外名称空间是开发的,即可以把名称加入到已有的名称空间中,也可以利用名称空间为声明的函数提供函数代码
#include <iostream>
#include <stdio.h>
#include "Header.h"
#include "Header2.h"
namespace Jake {
int age;//为Jake namespace添加成员变量age
void fetch()//为Jake中的方法fetch添加函数体
{
printf("%s\n","Jake");
}
}
int main(int argc, const char * argv[]) {
Jill::fetch=234;
Jake::fetch();
return 0;
}
作用域解析符(::)
未被装饰的名称(如pail)被称为未限定的名称,包含名称空间的名称(如Jack::pail)被称为限定的名称。
using声明和using编译指令
using声明:using Jill::fetch;
using编译指令:using namespace Jill;
using 声明使特定的操作符可用,using编译指令使整个名称空间可用
using声明将特定的名称添加到它所属的声明区域中,如果在main函数中使用using声明 Jill::fetch将fetch添加到main()定义的声明区域中,完成该声明后便可以使用名称fetch代替Jill::fetch
看代码演示:
#include <iostream>
#include <stdio.h>
#include "Header.h"
#include "Header2.h"
int fetch;
int main(int argc, const char * argv[]) {
using Jill::fetch;
fetch=234;
::fetch=678;
printf("外面定义的fetch=%d,Jill中的fetch=%f\n",::fetch,fetch);
return 0;
}
using声明与using编译指令比较
使用using声明
使用using编译指令