C++::namespace

命名空间是ANSIC++引入的可以由用户命名的作用域,用来处理程序中常见的同名冲突。在C语言中定义了3个层次的作用域,即文件(编译单元)、函数和复合语句。C++又引入了类作用域,类是出现在文件内的。在不同的作用域中可以定义相同名字的变量,互不于扰,系统能够区别它们。

 1、全局变量的作用域是整个程序,在同一作用域中不应有两个或多个同名的实体(enuty),包括变量、函数和类等。 

在文件中可以定义全局变量(global variable),它的作用域是整个程序。如果在文件A中定义了一个变量a        int a=3;  在文件B中可以再定义一个变量a       int a=5;  在分别对文件A和文件B进行编译时不会有问题。但是,如果一个程序包括文件A和文件B,那么在进行连接时,会报告出错,因为在同一个程序中有两个同名的变量,认为是对变量的重复定义。     可以通过extern声明同一程序中的两个文件中的同名变量是同一个变量。

如果在文件B中有以下声明:      

  extem int a; 

    表示文件B中的变量a是在其他文件中已定义的变量。由于有此声明,在程序编译和连接后,文件A的变量a的作用域扩展到了文件B。如果在文件B中不再对a赋值,则在文件B中用以下语句输出的是文件A中变量a的值: cout<<a; //得到a的值为3 

 2、程序中就会出现名字冲突。     在简单的程序设计中,只要人们小心注意,可以争取不 发生错误。但是,一个大型的应用软件, 往往不是由一个人独立完成的,而是由若干人合作完成的,不同的人分别完成不同的部分,最后组合成一个完整的程序。假 如不同的人分别定义了类,放在不同的头文件中,在主文件(包含主函数的文件)需要用这些类时,就用#include命令行将这些头文件包含进来。由于各头 文件是由不同的人设计的,有可能在不同的头文件中用了相同的名字来命名所定义的类或函数。

3、全局命名空间污染(global namespace pollution)。     在程序中还往往需要引用一些库(包括C++编译系统提供的库、由软件开发商提供的库或者用户自己开发的库),为此需要包含有关的头文件。如果在这些库中包含有与程序的全局实体同名的实体,或者不同的库中有相同的实体名,则在编译时就会出现名字冲突。

为 了避免这类问题的出现,人们提出了许多方法,例如:将实体的名字写得长—些(包含十几个或 几十个字母和字符);把名字起得特殊一些,包括一些特殊的字符; 由编译系统提供的内部全局标识符都用下划线作为前缀,如_complex(),以避免与用户命名的实体同名;由软件开发商提供的实体的名字用特定的字符作 为前缀。但是这样的效果并不理想,而且增加了阅读程序的难度,可读性降低了。     C 语言和早期的C++语言没有提供有效的机制来解决这个问题,没有使库的提供者能够建立自己的命名空间的工具。人们希望ANSI C++标准能够解决这个问题,提供—种机制、一种工具,使由库的设计者命名的全局标识符能够和程序的全局实体名以及其他库的全局标识符区别开来。

二、 什么是命名空间(解决方案)     命名空间:实际上就是一个由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有名字的空间域,把一些全局实体分别放在各个命名空间中,从而与其他全局实体分隔开来。  如:

 namespace ns1 //指定命名中间nsl   

    { int a;       double b; } 

 namespace是定义命名空间所必须写的关键字,nsl是用户自己指定的命名空间的名字(可以用任意的合法标识符,这里用ns1是因为ns是namespace的缩写,含义请楚),在花括号内是声明块,在其中声明的实体称为命名空间成员(namespace member)。现在命名空间成员包括变量a和b,注意a和b仍然是全局变量,仅仅是把它们隐藏在指定的命名空间中而已。如果在程序中要使用变量a和b,必须加上命名空间名和作用域分辨符“::”,如nsl::a,nsl::b。这种用法称为命名空间限定(qualified), 这些名字(如nsl::a)称为被限定名(qualified name)。C++中命名空间的作用类似于操作系统中的目录和文件的关系,由于文件很多,不便管理,而且容易重名,于是人们设立若干子目录,把文件分别放 到不同的子目录中,不同子目录中的文件可以同名。调用文件时应指出文件路径。

     命名空间的作用:是建立一些互相分隔的作用域,把一些全局实体分隔开来。以 免产生老点名叫李相国时,3个人都站起来应答,这就是名字冲突,因为他们无法辨别老师想叫的是哪一个李相国,同名者无法互相区分。为了避免同名混淆,学校 把3个同名的学生分在3个班。这样,在小班点名叫李相国时,只会有一个人应答。也就是说,在该班的范围(即班作用域)内名字是惟一的。如果在全校集合时校 长点名,需要在全校范围内找这个学生,就需要考虑作用域问题。如果校长叫李相国,全校学生中又会有3人一齐喊“到”,因为在同一作用域中存在3个同名学 生。为了在全校范围内区分这3名学生,校长必须在名字前加上班号,如高三甲班的李相国,或高三乙班的李相国,即加上班名限定。这样就不致产生混淆。     可 以根据需要设置许多个命名空间,每个命名空间名代表一个不同的命名空间域,不同的命名空间不能同名。

    这样,可以把不同的库中的实体放到不同的命名空间中, 或者说,用不同的命名空间把不同的实体隐蔽起来。过去我们用的全局变量可以理解为全局命名空间,独立于所有有名的命名空间之外,它是不需要用 namespace声明的,实际上是由系统隐式声明的,存在于每个程序之中。  在声明一个命名空间时,花括号内不仅可以包括变量,而且还可以包括以下类型: ·变量(可以带有初始化); ·常量;   ·数(可以是定义或声明); ·结构体; ·类; ·模板;  ·命名空间(在一个命名空间中又定义一个命名空间,即嵌套的命名空间)。

1 、使用命名空间别名  可以为命名空间起一个别名(namespace alias),用来代替较长的命名空间名。如 namespace Television //声明命名空间,名为Television { ... }  可以用一个较短而易记的别名代替它。如:

  namespace TV=Television; //别名TV与原名Television等价 

 也可以说,别名TV指向原名Television,在原来出现Television的位置都可以无条件地用TV来代替。

参考文献: http://wenku.baidu.com/link?url=zbfYlx7myQD1jte87zfqgdXvnxucvwWZuJ7feR4bx2jRa5eB--NqEQ3_BmTY87NqBZlQS9-5M9Djebcnq3zcLVC2WUMwF5jKtOO-AG2oN3O
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值