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

上传人:宝路 文档编号:52462931 上传时间:2018-08-21 格式:PPTX 页数:27 大小:197.44KB
返回 下载 相关 举报
零点起飞学C之命名空间和作用域_第1页
第1页 / 共27页
零点起飞学C之命名空间和作用域_第2页
第2页 / 共27页
零点起飞学C之命名空间和作用域_第3页
第3页 / 共27页
零点起飞学C之命名空间和作用域_第4页
第4页 / 共27页
零点起飞学C之命名空间和作用域_第5页
第5页 / 共27页
点击查看更多>>
资源描述

《零点起飞学C之命名空间和作用域》由会员分享,可在线阅读,更多相关《零点起飞学C之命名空间和作用域(27页珍藏版)》请在金锄头文库上搜索。

1、第14章 命名空间和作用域 命名空间(namespace)是一种将相关的类型进行分组的 逻辑命名方案。它将各种命名实体进行分组,各组间可以 互不影响,避免出现重名,这与Java的包机制类似。学习 本章,读者可以更好理解大型开发中的各种设计规划,更 好地深入学习项目构建。14.1 为什么使用命名空间 程序员在给对象命名时,一般都会使用一些有意义的记号 ,这些记号包括单词、汉语拼音,或者缩写等。所以很可 能出现多个实体拥有不同的功能却有相同的名称。但是, C+中采用的是单一的全局变量命名空间,在这单一的空 间中,实体必须有唯一的名字。但现实中经常会出现同名 现象,这种命名冲突被称为名字污染。 当然

2、,为了解决这一问题,程序员可以尽量给自己的实体 命名一个特有的名字。比如myString、stringOfTom等。甚 至可以在实体名称上加上一个随机的编码,如string6547 、string82734798等。但是这样做不仅意义不明确,而且 无论在使用时还是修改时都很不方便。更为糟糕的是,有 时程序员不得不将实体命名为一个简单而容易冲突的名字 ,如user_name、password、login等。为了从根本上解决名字污染问题,C+引入了命名空间的命名 机制,它提供了一种组织相关实体的逻辑方式。可以将命名空 间理解为一个文件夹,其内的对象就像一个个文件,不同文件 夹内的文件可以重名。在使

3、用重名的文件时,只需要说明是哪 个文件夹下的就行了。但它与文件夹又有本质上的区别,命名 空间是一种逻辑组合,而不是文件夹那样的物理组合。 命名空间为实体提供了上下文环境。一个实体可在多个命名空 间中定义,它在不同命名空间中的命名是互不相干的。这样, 在一个新的命名空间中可定义任何实体,它们不会与任何已有 的实体发生冲突,因为已有的定义都处于其他命名空间中。 例如Tom是X公司的员工,另一个Tom是Y公司的员工。由于它 们在不同的公司,所以具有相同的名字并不会带来麻烦,因为 公司就相当于一个独立的名字空间。如果两人在同一家公司, 那将肯定会引起许多不必要的麻烦。14.2 定义命名空间 命名空间用

4、namespace来声明,后跟空间的名称,名称之 后是由花括号 包含起来的声明块。在一个名字空间内声 明的实体被称为名字空间成员(namespace member),每 个成员都必须指向该名字空间内的唯一实体,不同的名字 空间可以具有相同名字的成员。命名空间的格式如下所示。namsespace space_name . 其中,namespace是名字空间的关键字,space_name是空间的名 称,花括号内是命名的实体。实体可以是变量(可以带有初始 化)、常量、结构体、类等各种类型,也可以是另一个命名空 间。把一个实体放在名字空间中并不会改变其意义,唯一的不 同是这样的声明所引入的名字要与名字

5、空间名复合起来。 程序员可以根据需要设置多个命名空间,每个命名空间名代表 一个不同的命名空间域,但是不同的命名空间不能同名。【示例14-1】 两个名字空间。 分析:该示例定义了两个命名空间SpaceA和SpaceB,在两 个空间内都有同样的类名A和变量str,但是在使用时并没 有引入冲突。 注意:名字空间的说明与类的声明有点儿像,但是它不 能以“;”结束。 名字空间的定义可以是不连续的。可以将一个名字空间拆 成多个部分或跨越多个文件,但却具有同一个名字。这时 它们都将属于同一个名字空间,既名字空间的定义是可累 积的。例如,如果在上例中还有如下语句,变量hello将和 类A和串str同属空间Sp

6、aceA。 namespace SpaceA char *hello=“hello world“; 还可以将上述语句放在另一个文件内,使用时将该文件引 入,这样字符串hello仍然和示例中的命名空间SpaceA是同 一个空间。 名字空间还可以嵌套,既在名字空间内还可以有另一个名 字空间。例如,在示例14-1的名字空间SpaceA内还可以定 义另一个名字空间SpaceAA。【示例14-2】 在示例14-1中嵌入另一个空间的定义。 分析:空间SpaceAA被空间SpaceA嵌套在内部,它的成员 声明被隐藏在该嵌套域中。这样的成员会被自动地加上最 外层名字空间名,形成多空间前缀。所以,如果使用它就

7、需要写成: SpaceA:SpaceAA:str; 此外,名字空间中的名字部分也可以省略,这时就定义了 一个未命名的名字空间。例如,将示例中namespace SpaceB的名称SpaceB去掉,就定义了一个未命名的名字空 间。未命名空间的实体将只在定义它的文件内有效。不像 其他的名字空间,未命名的名字空间的定义局部于定义它 的文件内,而不能跨越多个文本文件。14.3 如何使用命名空间 使用命名空间有两种方法:域限定符和使用using声明。下 面将分别介绍它们的用法和别名的用法。1使用域限定符 域限定符是:,其使用方法如下所示。 space_name:space_member; 如果命名空间是

8、嵌套的,则要连续写出所有空间名。 space_name1:space_name2:.:space_nameN:space_membe r; 但是,如果实体在未命名的空间内,则可以直接访问,就 像一个全局变量一样。2使用using声明命名空间 一个using声明一次只能作用于一个命名空间,它明确指出 了用到的命名空间。其格式如下: using namespace name_space; using name_space:space_memeber; 第一种方式表示将命名空间引入到该文件中,以后对该命 名空间内的成员访问时,就不需要加完整的空间限定了。 第二种方式表示只引入space_member

9、这一个成员,而其他 成员不可见。3别名 有时名字空间的命名太长不方便使用,这时可以给它定义 一个别名。 namespace othername=space_name; 当使用space_name时,就可以用名字othername来替代。假 设有命名空间MyFirstNameSpace,在不引起歧义和冲突的 情况下,可以给它一个别名My。【示例14-3】 给名字空间MyFirstNameSpace定义另一个别名。 namespace My=MyFirstNameSpace; 分析:以后就可以使用My,就像直接使用 MyFirstNameSpace一样。【示例14-4】 演示一个名字空间的完整使用

10、示例,文件otherfile.h定义 一个名字空间OtherFile。 文件test14_4.cpp中的代码使用了otherfile.h中定义的名字空 间。 分析:该示例定义了3个名字空间OtherFile和ThisFile,以 及1个未命名的空间。使用OtherFile时,需要将它所在的 文件包含进来,而且使用了using将该名字空间进行了声 明。所以,如果不加限定,则变量str和函数fun都将是命 名空间OtherFile的成员。而要使用ThisFile的成员就必须加 限定域。unnamed在未命名空间内,所以可以直接访问。 技巧:使用未命名的名字空间可以取代static限定,将实 体的作

11、用域限定在一个文件内部。14.4 我的地盘我做主作用域 作用域就是实体的作用范围,它限定了某个实体的生存期 和有效期。作用域是编程中经常要考虑的问题,也是经常 会出现问题的地方。本节将详细讲解C+中的各种作用域 的概念和注意事项。14.4.1 什么叫作用域 程序中的实体名字并不总是有效或可用的,它有效或可用 的代码范围就是它的作用域。作用域的使用提高了程序逻 辑的局部性,增强了程序的可靠性,减少了名字冲突。在 C+中作用域可以从5个层面来理解。 文件作用域:也称做全局作用域,它限定实体的作用范围 仅在某个文件内; 命名空间:它限定实体的作用范围仅在某个命名空间内, 命名空间可以跨越多个文件;

12、类作用域:它限定实体的作用范围仅在该类内有效; 函数作用域:它限定实体仅在声明它的函数内有效; 块作用域:也叫局部作用域,它限定实体仅在一个花括号 内有效。14.4.2 作用域的分类 对应于14.4.2节,作用域可以从5个层面来划分,分别是文 件作用域、命名空间、类作用域、函数作用域以及块作用 域等。1文件作用域 文件作用域是全局的,它在所有其他作用域之外说明。其 作用域从定义处开始,一直延伸到源文件结束。如果某个 文件被引入到另一个文件中,则原文件中的作用域也扩展 到该文件中,直到该文件结束。但是如果用static来修饰实 体,该实体将仅在定义它的文件内有效。用户也可以用匿 名名字空间来代替

13、static修饰符。每个文件都有一个匿名名 字空间,不同文件的匿名空间互不影响。2命名空间 命名空间的引入目的是为了解决名字冲突的问题。如果不 使用命名空间,就必须给全局变量和函数赋予特定名字, 以防止名字冲突。使用名字空间,就可以使用名字空间的 限定来避免名字冲突的问题。当然更主要的是可以通过名 字空间别名,使用声明(特定的名字)和使用指示(全部 名字)来达到既能有效防止冲突,又能在已确定的上下文 中更方便地访问名字的作用。3类作用域当用struct和class定义一个自定义类型时,就定义了一个类作用 域。它指在类的定义中由一对花括号所包含起来的部分。处于 类作用域下的变量和函数通常被称为成

14、员变量和成员函数,它 们可以是静态的(属于类型),也可以是非静态的(属于实例 )。静态的成员变量和成员函数与非成员变量和函数类似,而 类型在这里只是起到一个特殊的名字空间的作用,公共的静态 成员函数如果是可见的,那也是可访问的,也就具备外部链接 的能力。 在类的定义中可知,类域中可以定义变量,也可以定义函数。 从这一点上看类域与文件域很相似。但是,类域又不同于文件 域。在类域中定义的变量不能使用auto、register和extern等修饰 符,只能用static修饰符,而定义的函数也不能用extern修饰 符。另外,在类域中的静态成员和成员函数还具有外部的连接 属性。4函数作用域 每个函数都

15、构成了一个函数域,函数域的概念跟变量的存 储位置和生命期有关。函数的参数和在函数中声明并定义 的变量被称为局部变量或者是自动变量。它们分配在堆栈 上。它们随着函数的执行而生成,随着函数的退出而消 亡。而静态成员变量和非成员变量则分配在静态存储区中 ,它们的位置是固定的,生命期从程序启动一直到程序关 闭。5块作用域 局部域的作用通常是用来进一步限制局部变量的使用范 围。在某个局部域声明的局部变量,在退出该局部域时会 被自动销毁。用户自己产生的代码块(局部域)多用于所 谓的关键区,用来同步线程对外部状态的访问。如果函数 需要写的很长,刻意地区分不同的局部域也有助于代码的 可读性和防止不必要的错误。

16、 技巧:当局部变量和全局变量同名时,所有对变量名的 引用都会指向局部变量。此时,如果使用全局变量,就要 用作用域解析符:来限定变量。【示例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冲突

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 中学教育 > 教学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号