零点起飞学C之命名空间和作用域

上传人:wu****ei 文档编号:248467495 上传时间:2024-10-24 格式:PPTX 页数:27 大小:254.67KB
返回 下载 相关 举报
零点起飞学C之命名空间和作用域_第1页
第1页 / 共27页
零点起飞学C之命名空间和作用域_第2页
第2页 / 共27页
零点起飞学C之命名空间和作用域_第3页
第3页 / 共27页
点击查看更多>>
资源描述
第,14,章 命名空间和作用域,命名空间(,namespace,)是一种将相关的类型进行分组的逻辑命名方案。它将各种命名实体进行分组,各组间可以互不影响,避免出现重名,这与,Java,的包机制类似。学习本章,读者可以更好理解大型开发中的各种设计规划,更好地深入学习项目构建。,14.1,为什么使用命名空间,程序员在给对象命名时,一般都会使用一些有意义的记号,这些记号包括单词、汉语拼音,或者缩写等。所以很可能出现多个实体拥有不同的功能却有相同的名称。但是,,C+,中采用的是单一的全局变量命名空间,在这单一的空间中,实体必须有唯一的名字。但现实中经常会出现同名现象,这种命名冲突被称为名字污染。,当然,为了解决这一问题,程序员可以尽量给自己的实体命名一个特有的名字。比如,myString,、,stringOfTom,等。甚至可以在实体名称上加上一个随机的编码,如,string6547,、,string82734798,等。但是这样做不仅意义不明确,而且无论在使用时还是修改时都很不方便。更为糟糕的是,有时程序员不得不将实体命名为一个简单而容易冲突的名字,如,user_name,、,password,、,login,等。,为了从根本上解决名字污染问题,,C+,引入了命名空间的命名机制,它提供了一种组织相关实体的逻辑方式。可以将命名空间理解为一个文件夹,其内的对象就像一个个文件,不同文件夹内的文件可以重名。在使用重名的文件时,只需要说明是哪个文件夹下的就行了。但它与文件夹又有本质上的区别,命名空间是一种逻辑组合,而不是文件夹那样的物理组合。,命名空间为实体提供了上下文环境。一个实体可在多个命名空间中定义,它在不同命名空间中的命名是互不相干的。这样,在一个新的命名空间中可定义任何实体,它们不会与任何已有的实体发生冲突,因为已有的定义都处于其他命名空间中。,例如,Tom,是,X,公司的员工,另一个,Tom,是,Y,公司的员工。由于它们在不同的公司,所以具有相同的名字并不会带来麻烦,因为公司就相当于一个独立的名字空间。如果两人在同一家公司,那将肯定会引起许多不必要的麻烦。,14.2,定义命名空间,命名空间用,namespace,来声明,后跟空间的名称,名称之后是由花括号,包含起来的声明块。在一个名字空间内声明的实体被称为名字空间成员(,namespace member,),每个成员都必须指向该名字空间内的唯一实体,不同的名字空间可以具有相同名字的成员。,命名空间的格式如下所示。,namsespace space_name,.,其中,,namespace,是名字空间的关键字,,space_name,是空间的名称,花括号内是命名的实体。实体可以是变量(可以带有初始化)、常量、结构体、类等各种类型,也可以是另一个命名空间。把一个实体放在名字空间中并不会改变其意义,唯一的不同是这样的声明所引入的名字要与名字空间名复合起来。,程序员可以根据需要设置多个命名空间,每个命名空间名代表一个不同的命名空间域,但是不同的命名空间不能同名。,【,示例,14-1,】,两个名字空间。,分析:该示例定义了两个命名空间,SpaceA,和,SpaceB,,在两个空间内都有同样的类名,A,和变量,str,,但是在使用时并没有引入冲突。,注意:名字空间的说明与类的声明有点儿像,但是它不能以“,;,”结束。,名字空间的定义可以是不连续的。可以将一个名字空间拆成多个部分或跨越多个文件,但却具有同一个名字。这时它们都将属于同一个名字空间,既名字空间的定义是可累积的。例如,如果在上例中还有如下语句,变量,hello,将和类,A,和串,str,同属空间,SpaceA,。,namespace SpaceA,char,*,hello=hello world;,还可以将上述语句放在另一个文件内,使用时将该文件引入,这样字符串,hello,仍然和示例中的命名空间,SpaceA,是同一个空间。,名字空间还可以嵌套,既在名字空间内还可以有另一个名字空间。例如,在示例,14-1,的名字空间,SpaceA,内还可以定义另一个名字空间,SpaceAA,。,【,示例,14-2】,在示例,14-1,中嵌入另一个空间的定义。,分析:空间,SpaceAA,被空间,SpaceA,嵌套在内部,它的成员声明被隐藏在该嵌套域中。这样的成员会被自动地加上最外层名字空间名,形成多空间前缀。所以,如果使用它就需要写成:,SpaceA:SpaceAA:str;,此外,名字空间中的名字部分也可以省略,这时就定义了一个未命名的名字空间。例如,将示例中,namespace SpaceB,的名称,SpaceB,去掉,就定义了一个未命名的名字空间。未命名空间的实体将只在定义它的文件内有效。不像其他的名字空间,未命名的名字空间的定义局部于定义它的文件内,而不能跨越多个文本文件。,14.3,如何使用命名空间,使用命名空间有两种方法:域限定符和使用,using,声明。下面将分别介绍它们的用法和别名的用法。,1,使用域限定符,域限定符是,:,,其使用方法如下所示。,space_name:space_member;,如果命名空间是嵌套的,则要连续写出所有空间名。,space_name1:space_name2:.:space_nameN:space_member;,但是,如果实体在未命名的空间内,则可以直接访问,就像一个全局变量一样。,2,使用,using,声明命名空间,一个,using,声明一次只能作用于一个命名空间,它明确指出了用到的命名空间。其格式如下:,using namespace name_space;,using name_space:space_memeber;,第一种方式表示将命名空间引入到该文件中,以后对该命名空间内的成员访问时,就不需要加完整的空间限定了。第二种方式表示只引入,space_member,这一个成员,而其他成员不可见。,3,别名,有时名字空间的命名太长不方便使用,这时可以给它定义一个别名。,namespace othername=space_name;,当使用,space_name,时,就可以用名字,othername,来替代。假设有命名空间,MyFirstNameSpace,,在不引起歧义和冲突的情况下,可以给它一个别名,My,。,【,示例,14-3,】,给名字空间,MyFirstNameSpace,定义另一个别名。,namespace My=MyFirstNameSpace;,分析:以后就可以使用,My,,就像直接使用,MyFirstNameSpace,一样。,【,示例,14-4,】,演示一个名字空间的完整使用示例,文件,otherfile.h,定义一个名字空间,OtherFile,。,文件,test14_4.cpp,中的代码使用了,otherfile.h,中定义的名字空间。,分析:该示例定义了,3,个名字空间,OtherFile,和,ThisFile,,以及,1,个未命名的空间。使用,OtherFile,时,需要将它所在的文件包含进来,而且使用了,using,将该名字空间进行了声明。所以,如果不加限定,则变量,str,和函数,fun,都将是命名空间,OtherFile,的成员。而要使用,ThisFile,的成员就必须加限定域。,unnamed,在未命名空间内,所以可以直接访问。,技巧:使用未命名的名字空间可以取代,static,限定,将实体的作用域限定在一个文件内部。,14.4,我的地盘我做主,作用域,作用域就是实体的作用范围,它限定了某个实体的生存期和有效期。作用域是编程中经常要考虑的问题,也是经常会出现问题的地方。本节将详细讲解,C+,中的各种作用域的概念和注意事项。,14.4.1,什么叫作用域,程序中的实体名字并不总是有效或可用的,它有效或可用的代码范围就是它的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字冲突。在,C+,中作用域可以从,5,个层面来理解。,文件作用域:也称做全局作用域,它限定实体的作用范围仅在某个文件内;,命名空间:它限定实体的作用范围仅在某个命名空间内,命名空间可以跨越多个文件;,类作用域:它限定实体的作用范围仅在该类内有效;,函数作用域:它限定实体仅在声明它的函数内有效;,块作用域:也叫局部作用域,它限定实体仅在一个花括号内有效。,14.4.2,作用域的分类,对应于节,作用域可以从,5,个层面来划分,分别是文件作用域、命名空间、类作用域、函数作用域以及块作用域等。,1,文件作用域,文件作用域是全局的,它在所有其他作用域之外说明。其作用域从定义处开始,一直延伸到源文件结束。如果某个文件被引入到另一个文件中,则原文件中的作用域也扩展到该文件中,直到该文件结束。但是如果用,static,来修饰实体,该实体将仅在定义它的文件内有效。用户也可以用匿名名字空间来代替,static,修饰符。每个文件都有一个匿名名字空间,不同文件的匿名空间互不影响。,2,命名空间,命名空间的引入目的是为了解决名字冲突的问题。如果不使用命名空间,就必须给全局变量和函数赋予特定名字,以防止名字冲突。使用名字空间,就可以使用名字空间的限定来避免名字冲突的问题。当然更主要的是可以通过名字空间别名,使用声明(特定的名字)和使用指示(全部名字)来达到既能有效防止冲突,又能在已确定的上下文中更方便地访问名字的作用。,3,类作用域,当用,struct,和,class,定义一个自定义类型时,就定义了一个类作用域。它指在类的定义中由一对花括号所包含起来的部分。处于类作用域下的变量和函数通常被称为成员变量和成员函数,它们可以是静态的(属于类型),也可以是非静态的(属于实例)。静态的成员变量和成员函数与非成员变量和函数类似,而类型在这里只是起到一个特殊的名字空间的作用,公共的静态成员函数如果是可见的,那也是可访问的,也就具备外部链接的能力。,在类的定义中可知,类域中可以定义变量,也可以定义函数。从这一点上看类域与文件域很相似。但是,类域又不同于文件域。在类域中定义的变量不能使用,auto,、,register,和,extern,等修饰符,只能用,static,修饰符,而定义的函数也不能用,extern,修饰符。另外,在类域中的静态成员和成员函数还具有外部的连接属性。,4,函数作用域,每个函数都构成了一个函数域,函数域的概念跟变量的存储位置和生命期有关。函数的参数和在函数中声明并定义的变量被称为局部变量或者是自动变量。它们分配在堆栈上。它们随着函数的执行而生成,随着函数的退出而消亡。而静态成员变量和非成员变量则分配在静态存储区中,它们的位置是固定的,生命期从程序启动一直到程序关闭。,5,块作用域,局部域的作用通常是用来进一步限制局部变量的使用范围。在某个局部域声明的局部变量,在退出该局部域时会被自动销毁。用户自己产生的代码块(局部域)多用于所谓的关键区,用来同步线程对外部状态的访问。如果函数需要写的很长,刻意地区分不同的局部域也有助于代码的可读性和防止不必要的错误。,技巧:,当局部变量和全局变量同名时,所有对变量名的引用都会指向局部变量。此时,如果使用全局变量,就要用作用域解析符,:,来限定变量。,【,示例,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,文件中的,fun,和,str,冲突。主函数,main(),内又定义了,str1,,它是局部的,将会和全局的,str1,冲突。因此访问全局的,str1,时,需要用限定符,:,。,说明:,作用域一般都会具有三个特征,在同一作用域中不应有两个或多个同名的实体;没有互相包含关系的不同作用域声明同名标识符互不影响;如果两个或多个具有包含关系的作用域中声明了同名标识符,则外层的实体在内层不可见。,14.5,小 结,本章主要讲解了命名空间和作用域。重点是理解命名空间为什么会出现?难点是理解实体的作用域。第,15,章将讲解类的另一特征:继承和派生。,
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!