版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第14章 命名空间和作用域命名空间(namespace)是一种将相关的类型进行分组的逻辑命名方案。它将各种命名实体进行分组,各组间可以互不影响,避免出现重名,这与Java的包机制类似。学习本章,读者可以更好理解大型开发中的各种设计规划,更好地深入学习项目构建。14.1 为什么使用命名空间程序员在给对象命名时,一般都会使用一些有意义的记号,这些记号包括单词、汉语拼音,或者缩写等。所以很可能出现多个实体拥有不同的功能却有相同的名称。但是,C+中采用的是单一的全局变量命名空间,在这单一的空间中,实体必须有唯一的名字。但现实中经常会出现同名现象,这种命名冲突被称为名字污染。当然,为了解决这一问题,程序
2、员可以尽量给自己的实体命名一个特有的名字。比如myString、stringOfTom等。甚至可以在实体名称上加上一个随机的编码,如string6547、string82734798等。但是这样做不仅意义不明确,而且无论在使用时还是修改时都很不方便。更为糟糕的是,有时程序员不得不将实体命名为一个简单而容易冲突的名字,如user_name、password、login等。为了从根本上解决名字污染问题,C+引入了命名空间的命名机制,它提供了一种组织相关实体的逻辑方式。可以将命名空间理解为一个文件夹,其内的对象就像一个个文件,不同文件夹内的文件可以重名。在使用重名的文件时,只需要说明是哪个文件夹下的
3、就行了。但它与文件夹又有本质上的区别,命名空间是一种逻辑组合,而不是文件夹那样的物理组合。命名空间为实体提供了上下文环境。一个实体可在多个命名空间中定义,它在不同命名空间中的命名是互不相干的。这样,在一个新的命名空间中可定义任何实体,它们不会与任何已有的实体发生冲突,因为已有的定义都处于其他命名空间中。例如Tom是X公司的员工,另一个Tom是Y公司的员工。由于它们在不同的公司,所以具有相同的名字并不会带来麻烦,因为公司就相当于一个独立的名字空间。如果两人在同一家公司,那将肯定会引起许多不必要的麻烦。14.2 定义命名空间命名空间用namespace来声明,后跟空间的名称,名称之后是由花括号 包
4、含起来的声明块。在一个名字空间内声明的实体被称为名字空间成员(namespace member),每个成员都必须指向该名字空间内的唯一实体,不同的名字空间可以具有相同名字的成员。命名空间的格式如下所示。namsespace space_name.其中,namespace是名字空间的关键字,space_name是空间的名称,花括号内是命名的实体。实体可以是变量(可以带有初始化)、常量、结构体、类等各种类型,也可以是另一个命名空间。把一个实体放在名字空间中并不会改变其意义,唯一的不同是这样的声明所引入的名字要与名字空间名复合起来。程序员可以根据需要设置多个命名空间,每个命名空间名代表一个不同的命名
5、空间域,但是不同的命名空间不能同名。【示例14-1】 两个名字空间。分析:该示例定义了两个命名空间SpaceA和SpaceB,在两个空间内都有同样的类名A和变量str,但是在使用时并没有引入冲突。注意:名字空间的说明与类的声明有点儿像,但是它不能以“;”结束。名字空间的定义可以是不连续的。可以将一个名字空间拆成多个部分或跨越多个文件,但却具有同一个名字。这时它们都将属于同一个名字空间,既名字空间的定义是可累积的。例如,如果在上例中还有如下语句,变量hello将和类A和串str同属空间SpaceA。namespace SpaceAchar *hello=hello world;还可以将上述语句放
6、在另一个文件内,使用时将该文件引入,这样字符串hello仍然和示例中的命名空间SpaceA是同一个空间。名字空间还可以嵌套,既在名字空间内还可以有另一个名字空间。例如,在示例14-1的名字空间SpaceA内还可以定义另一个名字空间SpaceAA。【示例14-2】 在示例14-1中嵌入另一个空间的定义。分析:空间SpaceAA被空间SpaceA嵌套在内部,它的成员声明被隐藏在该嵌套域中。这样的成员会被自动地加上最外层名字空间名,形成多空间前缀。所以,如果使用它就需要写成:SpaceA:SpaceAA:str;此外,名字空间中的名字部分也可以省略,这时就定义了一个未命名的名字空间。例如,将示例中n
7、amespace SpaceB的名称SpaceB去掉,就定义了一个未命名的名字空间。未命名空间的实体将只在定义它的文件内有效。不像其他的名字空间,未命名的名字空间的定义局部于定义它的文件内,而不能跨越多个文本文件。14.3 如何使用命名空间使用命名空间有两种方法:域限定符和使用using声明。下面将分别介绍它们的用法和别名的用法。1使用域限定符域限定符是:,其使用方法如下所示。space_name:space_member;如果命名空间是嵌套的,则要连续写出所有空间名。space_name1:space_name2:.:space_nameN:space_member;但是,如果实体在未命名的
8、空间内,则可以直接访问,就像一个全局变量一样。2使用using声明命名空间一个using声明一次只能作用于一个命名空间,它明确指出了用到的命名空间。其格式如下:using namespace name_space;using name_space:space_memeber;第一种方式表示将命名空间引入到该文件中,以后对该命名空间内的成员访问时,就不需要加完整的空间限定了。第二种方式表示只引入space_member这一个成员,而其他成员不可见。3别名有时名字空间的命名太长不方便使用,这时可以给它定义一个别名。namespace othername=space_name;当使用space_na
9、me时,就可以用名字othername来替代。假设有命名空间MyFirstNameSpace,在不引起歧义和冲突的情况下,可以给它一个别名My。【示例14-3】 给名字空间MyFirstNameSpace定义另一个别名。namespace My=MyFirstNameSpace;分析:以后就可以使用My,就像直接使用MyFirstNameSpace一样。【示例14-4】 演示一个名字空间的完整使用示例,文件otherfile.h定义一个名字空间OtherFile。文件test14_4.cpp中的代码使用了otherfile.h中定义的名字空间。分析:该示例定义了3个名字空间OtherFile和
10、ThisFile,以及1个未命名的空间。使用OtherFile时,需要将它所在的文件包含进来,而且使用了using将该名字空间进行了声明。所以,如果不加限定,则变量str和函数fun都将是命名空间OtherFile的成员。而要使用ThisFile的成员就必须加限定域。unnamed在未命名空间内,所以可以直接访问。技巧:使用未命名的名字空间可以取代static限定,将实体的作用域限定在一个文件内部。14.4 我的地盘我做主作用域作用域就是实体的作用范围,它限定了某个实体的生存期和有效期。作用域是编程中经常要考虑的问题,也是经常会出现问题的地方。本节将详细讲解C+中的各种作用域的概念和注意事项。
11、14.4.1 什么叫作用域程序中的实体名字并不总是有效或可用的,它有效或可用的代码范围就是它的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。在C+中作用域可以从5个层面来理解。文件作用域:也称做全局作用域,它限定实体的作用范围仅在某个文件内;命名空间:它限定实体的作用范围仅在某个命名空间内,命名空间可以跨越多个文件;类作用域:它限定实体的作用范围仅在该类内有效;函数作用域:它限定实体仅在声明它的函数内有效;块作用域:也叫局部作用域,它限定实体仅在一个花括号内有效。14.4.2 作用域的分类对应于14.4.2节,作用域可以从5个层面来划分,分别是文件作用域、命名
12、空间、类作用域、函数作用域以及块作用域等。1文件作用域文件作用域是全局的,它在所有其他作用域之外说明。其作用域从定义处开始,一直延伸到源文件结束。如果某个文件被引入到另一个文件中,则原文件中的作用域也扩展到该文件中,直到该文件结束。但是如果用static来修饰实体,该实体将仅在定义它的文件内有效。用户也可以用匿名名字空间来代替static修饰符。每个文件都有一个匿名名字空间,不同文件的匿名空间互不影响。2命名空间命名空间的引入目的是为了解决名字冲突的问题。如果不使用命名空间,就必须给全局变量和函数赋予特定名字,以防止名字冲突。使用名字空间,就可以使用名字空间的限定来避免名字冲突的问题。当然更主
13、要的是可以通过名字空间别名,使用声明(特定的名字)和使用指示(全部名字)来达到既能有效防止冲突,又能在已确定的上下文中更方便地访问名字的作用。3类作用域当用struct和class定义一个自定义类型时,就定义了一个类作用域。它指在类的定义中由一对花括号所包含起来的部分。处于类作用域下的变量和函数通常被称为成员变量和成员函数,它们可以是静态的(属于类型),也可以是非静态的(属于实例)。静态的成员变量和成员函数与非成员变量和函数类似,而类型在这里只是起到一个特殊的名字空间的作用,公共的静态成员函数如果是可见的,那也是可访问的,也就具备外部链接的能力。在类的定义中可知,类域中可以定义变量,也可以定义
14、函数。从这一点上看类域与文件域很相似。但是,类域又不同于文件域。在类域中定义的变量不能使用auto、register和extern等修饰符,只能用static修饰符,而定义的函数也不能用extern修饰符。另外,在类域中的静态成员和成员函数还具有外部的连接属性。4函数作用域每个函数都构成了一个函数域,函数域的概念跟变量的存储位置和生命期有关。函数的参数和在函数中声明并定义的变量被称为局部变量或者是自动变量。它们分配在堆栈上。它们随着函数的执行而生成,随着函数的退出而消亡。而静态成员变量和非成员变量则分配在静态存储区中,它们的位置是固定的,生命期从程序启动一直到程序关闭。5块作用域局部域的作用通
15、常是用来进一步限制局部变量的使用范围。在某个局部域声明的局部变量,在退出该局部域时会被自动销毁。用户自己产生的代码块(局部域)多用于所谓的关键区,用来同步线程对外部状态的访问。如果函数需要写的很长,刻意地区分不同的局部域也有助于代码的可读性和防止不必要的错误。技巧:当局部变量和全局变量同名时,所有对变量名的引用都会指向局部变量。此时,如果使用全局变量,就要用作用域解析符:来限定变量。【示例14-5】 作用域的使用举例,文件other.h中定义一个函数fun()。主文件test14_5.cpp中使用other.h中定义的函数fun()。分析:该示例中,定义了命名空间mySpace、类myClass,它们的成员分别局限在命名空间和类内。函数fun1()和字符串str1是文件内全局有效。头文件other.h引入了另外两个实体fun和str,它们的作用域自动扩展到了主文件内,变成全局有效。所以,如果fun1和str1写成fun和str,则将会和other.h文件中的f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年xx村年度脱贫户、监测户增收工作总结
- 新修订《疫苗流通和预防接种管理条例》培训试题及答案
- 2024年简化货品采购协议格式
- 2024年限定区域分销商协议条款
- 2024年度工程领域劳务协议范本
- 2024年新汽车租赁经营协议样本
- 2024全新保健品商业合作协议样本
- 化现金借贷协议:2024年
- 2024年家居装修工程协议样本
- 2024年房产开发商住宅购买协议
- 《花样年华》的美学分析
- 山东省济南市历下区2023-2024学年八年级上学期期中语文试题
- 图神经网络在生物医学影像分析中的应用
- 浅谈管理者的自我管理
- 第一章 结构及其设计 课件-2023-2024学年高中通用技术苏教版(2019)必修《技术与设计2》
- 语文教学常规检查表
- “思政”课社会实践
- 临时用电漏电保护器运行检测记录表
- 复杂性尿路感染
- 重度残疾儿童送教上门
- 膀胱癌综合治疗新进展
评论
0/150
提交评论