C++名字空间/C++命名空间(一)

2014-11-24 12:38:48 · 作者: · 浏览: 0
0、序言
名字空间是C++提供的一种解决符号名字冲突的方法。
一个命令空间是一个作用域,在不同名字空间中命名相同的符号代表不同的实体。
通常,利用定义名字空间的办法,可以使模块划分更加方便,减少模块间的相互影响。
1、名字空间的成员
定义在名字空间中的实体称为名字空间的成员。
名字空间内的名字可以被该名字空间内的其他成员直接访问,名字空间外的代码必须指定该名字位于哪个名字空间。
一个名字空间可以包含多种类型的标识符,如下面所列:
变量、常量、函数、结构体/联合体/枚举、类、嵌套名字空间
名字空间成员的引用方法如下:
namespace_name::member_name
2、定义名字空间
(1)、一个名字空间可以在两个地方被定义:在全局范围层次或者是在另一个名字空间中被定义(这样就形成一个嵌套名字空间),不能在函数和类的内部定义。
(2)、名字空间可以是不连续的,他是由所有分离定义的部分的总体构成的。一个名字空间可以分散多个文件中,不同的文件中名字空间的定义也是累积的。
通常将名字空间的声明放到头文件中,实现放到源文件中。可以将不相关的成员放到不同的头文件中。
(3)、命令空间的作用域不能以分号结尾。
3、嵌套名字空间(Nested Namespce)
3.1、普通嵌套名字空间(ordinary nested namespace)
一个嵌套名字空间就是一个嵌套作用域,其作用域嵌套在包含他的名字空间中。
在外部引用嵌套空间中的成员时,使用下面的形式
包含嵌套空间的名字空间的名字::嵌套空间的名字::嵌套空间的成员
下面举例说明嵌套名字空间定义和使用
复制代码
#include
namespace MyOutNames
{
int iVal1 = 100;
int iVal2 = 200;
namespace MyInnerNames //定义嵌套名字空间
{
int iVal3 = 300;
int iVal4 = 400;
}
}
int main(void)
{
std::cout<
std::cout<
std::cout<
std::cout<
return 0;
}
复制代码
3.2、内联嵌套名字空间(Inline Namespace C++11)
C++11中,新增inline namespace,指示命名空间中的名称同时是外层命名空间直接包含的名称。这便于命名空间的版本管理,减少冲突。
inline描述符使得内联命名空间中的声明看起来就好像是直接在外围的命名空间中进行声明的一样。(使用inline关键字定义的内联名字空间成为默认名字空间。)
inline描述符由命名空间的设计者放置,即命名空间的作者可以通过放置inline描述符来表示当前最新的命名空间是哪个.
复制代码
// file V98.hpp:
namespace V98
{
void f(int); // does something
// ...
}
// file V99.hpp:
inline namespace V99
{
void f(int); // does something better than the V98 version
void f(double); // new feature
// ...
}
// file Mine.hpp:
namespace Mine
{
#include "V99.hpp"
#include "V98.hpp"
}
//file example.cpp
#include "Mine.hpp"
using namespace Mine;
// ...
V98::f(1); // old version
V99::f(1); // new version
f(1); //default version
复制代码
4、全局名字空间(Global Namespce)
定义在全局作用域的名字(在任意类、函数或命名空间外部声明的名字)是定义在全局命名空间中的。
全局命名空间是隐式声明的,存在于每个程序中。在全局作用域定义实体的每个文件将那些名字加到全局命名空间。
可以用作用域操作符引用全局命名空间的成员。因为全局命名空间是隐含的,它没有名字,
所以使用记号如下方法引用全局命名空间的成员。
::member_name
5、匿名名字空间(Unnamed Namespace)
命名空间可以是未命名的,未命名的命名空间在定义时没有给定名字。其定义方法如下:
namespace //No name
{
//members....
}
未命名的命名空间与其他命名空间不同,未命名的命名空间的定义局部于特定文件,从不跨越多个文本文件。
未命名的命名空间可以在给定文件中不连续,但不能跨越文件,每个文件有自己的未命名的命名空间。
未命名的命名空间用于声明局部于文件的实体。在未命名的命名空间中定义的变量在程序开始时创建,在程序结束之前一直存在。
未命名的命名空间中定义的名字可直接使用,因为没有命名空间名字来限定它们。
复制代码
#include
namespace //unnamed namespace
{
int count = 1;
}
using namespace std;
namespace //unnamed namespace
{
void name_printf(void)
{
cout << "count = " << count << endl;
}
}
int main(void)
{
count = 3; //直接使用
name_printf(); //直接使用
return 0;
}
复制代码
未命名的命名空间中定义的名字只在包含该命名空间的文件中可见。
如果另一文件包含一个未命名的命名空间,两个命名空间不相关,可以定义相同的名字,而这些定义将引用不同的实体。
未命名的命名空间中成员的名字不能与全局作用域中定义的名字相同。例子如下,函数也是同样的道理。
复制代码
int i; // global variable
namespace //unnamed namespace
{
int i;
}
// error: reference to ‘i’ is ambiguous
复制代码
像其他命名空间一样,未命名的命名空间也可以嵌