第15章 名称空间(Namespace)
Kubernetes学习之路(二十)之K8S组件运行原理详解总结

Kubernetes学习之路(⼆⼗)之K8S组件运⾏原理详解总结⽬录⼀、看图说K8S先从⼀张⼤图来观看⼀下K8S是如何运作的,再具体去细化K8S的概念、组件以及⽹络模型。
从上图,我们可以看到K8S组件和逻辑及其复杂,但是这并不可怕,我们从宏观上先了解K8S是怎么⽤的,再进⾏庖丁解⽜。
从上图我们可以看出:Kubernetes集群主要由Master和Node两类节点组成Master的组件包括:apiserver、controller-manager、scheduler和etcd等⼏个组件,其中apiserver是整个集群的⽹关。
Node主要由kubelet、kube-proxy、docker引擎等组件组成。
kubelet是K8S集群的⼯作与节点上的代理组件。
⼀个完整的K8S集群,还包括CoreDNS、Prometheus(或HeapSter)、Dashboard、Ingress Controller等⼏个附加组件。
其中cAdivsor组件作⽤于各个节点(master和node节点)之上,⽤于收集及收集容器及节点的CPU、内存以及磁盘资源的利⽤率指标数据,这些统计数据由Heapster聚合后,可以通过apiserver访问。
要了解K8S的所有组件,没去⾛⼀遍,永远不知道它是怎么跑起来的,那么下⾯就带着⼏个新⼿疑问来看K8S1、K8S是如何对容器编排?在K8S集群中,容器并⾮最⼩的单位,K8S集群中最⼩的调度单位是Pod,容器则被封装在Pod之中。
由此可知,⼀个容器或多个容器可以同属于在⼀个Pod之中。
2、Pod是怎么创建出来的?Pod并不是⽆缘⽆故跑出来的,它是⼀个抽象的l逻辑概念,那么Pod是如何创建的呢?Pod是由Pod控制器进⾏管理控制,其代表性的Pod控制器有Deployment、StatefulSet等。
这⾥我们先有这样的⼀个概念,后⾯再详细解刨。
3、Pod资源组成的应⽤如何提供外部访问的?Pod组成的应⽤是通过Service这类抽象资源提供内部和外部访问的,但是service的外部访问需要端⼝的映射,带来的是端⼝映射的⿇烦和操作的繁琐。
C++读书报告

《零基础学C++》读书报告一、作者简介:作者杨彦强,刘袁红,王浩等编著杨彦强:任职于方正集团,系统架构师,负责公司富客户端技术(包括Ext、OpenLaszlo、Flex)的调研与培训工作。
多年来专注于行业软件开发、架构设计。
擅长面向对象的分析设计、Java EE架构和Unix/Linux平台的编程技术。
一直关注开源事业,并致力于富客户端技术的研究,基于Ext JS框架已开发多个大型商业项目,具有精湛的Ext JS框架开发功力。
刘袁红:女,哈尔滨人,2005年毕业于哈尔滨工业大学职业技术学院计算机应用技术教育专业,本科,工学学士。
现工作于哈尔滨工业大学华德应用技术学院。
王浩:软件工程师。
任职于上市公司南天信息,担任项目经理二、内容概要:阅读和学习本书并不要求读者有C++语言的基础,通过几百个简洁高效的代码,本书将带领读者循序渐进地领略C++语言的魅力所在。
本书采用从无到有、由浅入深、逐级递进的编写方式,尤其适合无C++语言基础或C语言基础薄弱的程序员阅读。
本书共分为六篇21章,介绍了Visual C++6开发环境的搭建、C++语言的基本数据类型、C++语言的表达式、函数、函数重载、类的继承、多态、内存管理方式、文件存储、错误与异常、RTTI、String类、编码风格与程序编译等内容,最后还对世界500强中IT公司常见面试题进行了讲解。
本书非常适合C++语言的初、中级学者阅读,并可作为开发人员的参考手册。
三、书籍特色:1、由浅入深,循序渐进,从零开始学C++,一点都不难2、编程基础,编程进阶,编程应用,项目实战,上机练习,面试指南3、266个实例,42个练习题,68个面试题四、书籍内容:1、前言:2、第一篇C++基础:本篇是基础介绍,涵盖了程序设计语言的基本概念,Visual C++6开发环境的搭建、C++程序的构成、变量、常量、运算符与表达式、数据类型转换以及流程控制语句等内容。
第1章C++概述第2章开始C++之旅本章主要涉及以下知识点。
Vim IDE环境配置讲解

VIM IDE环境配置1 介绍要使VIM变成和VS一样的集成环境,可通过安装以下插件来实现,分别是1)Ctags2)Taglist3)GNU Global4)OmniCppComplete5)SuperTab6)Winmanager7)NERDTree8)MiniBufExplorer下面将分别介绍各个插件的安装与使用。
2 Ctags安装安装步骤:1)从/下载源代码包后,解压缩生成源代码目录。
2)进入源代码根目录执行./configure。
3)执行make。
4)编译成功后执行make install。
常用命令列表:1)$ ctags –R * ($ 为Linux系统Shell提示符)2)$ vim –t tag (请把tag替换为您欲查找的变量或函数名)3):ts (ts 助记字:tags list, “:”开头的命令为vim中命令行模式命令) 4):tp (tp 助记字:tags preview)5):tn (tn 助记字:tags next)6) Ctrl + ] (跳转到该标记的定义处)7) Ctrl + t (返回到上次跳转前位置)命令解释:1)“$ ctags –R *”:“-R”表示递归创建,也就包括源代码根目录(当前目录)下的所有子目录。
“*”表示所有文件。
2)这条命令会在当前目录下产生一个“tags”文件,当用户在当前目录中运行vim时,会自动载入此tags文件。
Tags文件中包括这些对象的列表:1)用#define定义的宏2)枚举型变量的值3)函数的定义、原型和声明4)名字空间(namespace)5)类型定义(typedefs)6)变量(包括定义和声明)7)类(class)、结构(struct)、枚举类型(enum)和联合(union)8)类、结构和联合中成员变量或函数Vim用这个“tags”文件来定位上面这些做了标记的对象。
注意:打开文件时要在运行ctags的目录下打开,不能进入子文件夹后再打开。
PHP命名空间(Namespace)的使用详解

PHP命名空间(Namespace)的使⽤详解命名空间⼀个最明确的⽬的就是解决重名问题,PHP中不允许两个函数或者类出现相同的名字,否则会产⽣⼀个致命的错误。
这种情况下只要避免命名重复就可以解决,最常见的⼀种做法是约定⼀个前缀。
例:项⽬中有两个模块:article和message board,它们各⾃有⼀个处理⽤户留⾔的类Comment。
之后我可能想要增加对所有⽤户留⾔的⼀些信息统计功能,⽐如说我想得到所有留⾔的数量。
这时候调⽤它们Comment提供的⽅法是很好的做法,但是同时引⼊各⾃的Comment类显然是不⾏的,代码会出错,在另⼀个地⽅重写任何⼀个Comment也会降低维护性。
那这时只能重构类名,我约定了⼀个命名规则,在类名前⾯加上模块名,像这样:Article_Comment、MessageBoard_Comment可以看到,名字变得很长,那意味着以后使⽤Comment的时候会写上更多的代码(⾄少字符多了)。
并且,以后如果要对各个模块增加更多的⼀些整合功能,或者是互相调⽤,发⽣重名的时候就需要重构名字。
当然在项⽬开始的时候就注意到这个问题,并规定命名规则就能很好的避免这个问题。
另⼀个解决⽅法可以考虑使⽤命名空间。
注明:本⽂提到的常量:PHP5.3开始const关键字可以⽤在类的外部。
const和define都是⽤来声明常量的(它们的区别不详述),但是在命名空间⾥,define的作⽤是全局的,⽽const则作⽤于当前空间。
我在⽂中提到的常量是指使⽤const声明的常量。
基础命名空间将代码划分出不同的空间(区域),每个空间的常量、函数、类(为了偷懒,我下边都将它们称为元素)的名字互不影响,这个有点类似我们常常提到的’封装’的概念。
创建⼀个命名空间需要使⽤namespace关键字,这样:<?php//创建⼀个名为'Article'的命名空间namespace Article;>要注意的是,当前脚本⽂件的第⼀个命名空间前⾯不能有任何代码,下⾯的写法都是错误的:例⼀//在脚本前⾯写了⼀些逻辑代码<?php$path = "/";class Comment { }namespace Article;>例⼆</html><?phpnamespace Article;>为什么要说第⼀个命名空间呢?因为同⼀脚本⽂件中可以创建多个命名空间。
第15章 讲座 关于名字空间(namespace)

C++高级程序设计
30 40 15.7 无名名字空间 可以通过在定义中省略名字空间的名称而简单地声明无名名字空间。 例子:定义了一个无名名字空间举例。 namespace //无名名字空间 { int val1 = 10; int val2 = 20; } 在无名名字空间中定义的标识符被设置为全局的名字空间。 无名名字空间几乎彻底破坏了名字空间设置的最初目标。因此,无名名字空间并未被 广泛应用。 15.8 名字空间的别名 可以为名字空间指定别名,它是已定义的名字空间的可替换的名称。 通过将别名指定给当前的名字空间的名称,可以简单地创建一个名字空间的别名。 例子:名字空间的别名定义举例。 namespace MyNames { int val1 = 10; int val2 = 20; } namespace MyAlias = MyNames; 例子:名字空间的别名应用举例。 namespace MyNames { int val1 = 10; int val2 = 20; } namespace MyAlias = MyNames; void main(void) { std::cout<<"Namespace values:"<<std::endl; std::cout<<MyNames::val1<<std::endl; std::cout<<MyNames::val2<<std::endl; std::cout<<"Alias namespace values:"<<std::endl; std::cout<<MyAlias::val1<<std::endl; std::cout<<MyAlias::val2<<std::endl; } 运行结果; Namespace values: 10
C#命名空间(namespace)不可不知的那些事

C#命名空间(namespace)不可不知的那些事 命名空间本质上就是⼀个逻辑分组,就和我们⽂件夹分组是⼀致的,允许我们将相关的类型集合在⼀起。
命名空间是⼀个⽐较通⽤的概念,在很多语⾔⾥⾯都存在,只不过可能存在⼀些细微差别以及使⽤不同的名称。
⽐如Java就叫包(package)。
接下来,我们将从以下五个⽅⾯来讲解命名空间: 定义命名空间使⽤命名空间正确理解命名空间含义使⽤命名空间alias解决简单类名冲突使⽤extern alias解决Assembly中的完整类名冲突定义命名空间 命名空间的定义很简单,是以关键字namespace(命名空间的英⽂名)开始,后跟命名空间的名字和⼀对⼤括号。
⼤括号⾥的内容都属于这个命名空间。
格式如下: namespace namespace_name { } namespace_name是以点号(.)作为层级隔离的。
⽐如System.IO就可以认为System是第⼀层命名空间,IO是第⼆层命名空间。
由于命名空间其实就是⼀个逻辑分组,所以namespace这个关键字,我们可以理解为“如果不存在namespace_name这个命名空间,就创建⼀个。
如果存在,就使⽤这个命名空间”。
因此,我们是可以在多个地⽅定义同⼀个命名空间的,只要保证同⼀个命名空间中的内容不冲突即可,如下: namespace System.IO { class MemoryStream {} } namespace System.IO { class BufferedStream {} }使⽤命名空间 在程序中使⽤特定类型的时候,我们需要使⽤完整的限定名,⽐如System.IO.MemoryStream。
但是如果每次都这么写,除了增加了开发⼈员打字的成本,毫⽆益处。
因此我们可以使⽤using关键字来表明我们需要使⽤某个命名空间中的类型。
如下: //使⽤完整限定名 public static void Main() { System.Text.StringBuilder sb=new System.Text.StringBuilder(); } //使⽤using 关键字 using System.Text; public static void Main() { StringBuilder sb=new StringBuilder(); } using关键字,其实是告诉编译器可以尝试在这个特定的命名空间中查找类型。
Hadoop题库(第1-3-8章)
题库(第一、三、八章)第一章单选题1、大数据的数据量现在已经达到了哪个级别?( C )A、GBB、TBC、PBD、ZB2、2003年,Google公司发表了主要讲解海量数据的可靠存储方法的论文是?( A )A、“The Google File System”B、“MapReduce: Simplified Data Processing on Large Clusters”C、“Bigtable: A Distributed Storage System for Structured Data”D、“The Hadoop File System”3、2004年,Google公司发表了主要讲解海量数据的高效计算方法的论文是?( B )A、“The Google File System”B、“MapReduce: Simplified Data Processing on Large Clusters”C、“Bigtable: A Distributed Storage System for Structured Data”D、“The Hadoop File System”4、2006年,Google公司发表了用来处理海量数据的一种非关系型数据库的论文是?( C )A、“The Google File System”B、“MapReduce: Simplified Data Processing on Large Clusters”C、“Bigtable: A Distributed Storage System for Structured Data”D、“The Hadoop File System”5、对于GFS架构,下面哪个说法是错误的?(A)A、GFS Master节点管理所有的文件系统所有数据块。
B、GFS存储的文件都被分割成固定大小的块,每个块都会被复制到多个块服务器上(可靠性)。
块的冗余度默认为3。
2、C#面向对象:封装、继承、多态、String、集合、文件(上)
2、C#⾯向对象:封装、继承、多态、String、集合、⽂件(上)⾯向对象封装⾯向对象概念⼀、⾯向对象概念⾯向过程:⾯向的是完成⼀件事情的过程,强调的是完成这件事情的动作。
⾯向对象:找个对象帮你完成这件事情。
⼆、⾯向对象封装把⽅法进⾏封装,隐藏实现细节,外部直接调⽤。
打包,便于管理,为了解决⼤型项⽬的维护与管理。
三、什么是类?将相同的属性和相同⽅法的对象进⾏封装,抽象出 “类”,⽤来确定对象具有的属性和⽅法。
类、对象关系:⼈是类,张三是⼈类的对象。
类是抽象的,对象是具体的。
对象可以叫做类的实例,类是不站内存的,对象才占内存。
字段是类的状态,⽅法是类执⾏的动作。
三个特性:封装、继承、多态。
四、访问修饰符public 公共的,任何地⽅都可以访问private 私有的,只有本类中成员可以访问protected 受保护的,可以在当前类以及⼦类访问Intelnal 只能在当前项⽬中访问,在同⼀个项⽬中Intelnal和public权限是⼀样的。
protected Intelnal 当前项⽬受保护的。
修饰类的访问修饰符只有两个:public、Intelnal定义⼀个类时,如果不加访问修饰符,默认是Intelnal可访问性不⼀致:⼦类可访问性不能⾼于⽗类可访问性,可能会被暴漏⽗类成员。
类中的成员,如果不加访问修饰符,默认都是private定义⼀个类[public] class 类名{字段;属性;⽅法;}class person{public string name; //字段public int age;public int height;public void sayHi(){Console.WriteLine("Hello , my name is {0}, my age is {1} , my height is {2}" , , this.age,this.height); //this当前类}}使⽤关键字 new 创建类的对象称之为实例化。
第七周教案 windows server 2008域服务的配置与管理
2015-2016学年度网络、网站专业班 windows server 2008 网络操作系统课程教案从安全管理角度讲,域是安全的边界;6) 域树一组具有连续命名空间的域组成的;域通过自动建立的信任关系连接起来;根域:最上层的域名就属于这棵域树的根域子域:根域下面的两个域就属于子域,它包含了上一层父域的域名。
7) 域林由一棵或多棵域树组成的;每棵域树独享连续的命名空间;不同域树之间没有命名空间的连续性;域林中第一个创建的域称为域林根域,根域不可删除、更改和重命名。
8) 组织单位(ou)组织、管理一个域内对象的容器包容用户账户、用户组、计算机、打印机和其他的组织单位具有很清楚的层次结构,管理员可以根据自身的要求进行定义。
课间休息(10min)找出图片中三个域的相同之处? 2015-2016学年度网络、网站专业班 windows server 2008 网络操作系统实训课教案3.安装活动目录(1)启动Active Directory域服务安装向导;方法一:【服务器管理器】窗口方法二:运行dcpromo命令安装活动目录(2) 在【Active Directory域服务安装向导】欢迎界面中,确定是否使用高级模式安装;(3) 在【操作系统兼容性】向导页中,提示Windows Server 2008中改进的安全设置会影响老版本的Windows,单击【下一步】;((4)如果系统的TCP/IP配置中没有配置首选DNS服务器IP地址时,将打开【配置域系统客户端设置】向导页,提示必须要配置DNS客户端。
可以选中复选框即在这个服务器中安装DNS服务;(5) 在【选择某一部署配置】向导页中,若要创建一台全新的域控制器,则选择【在新林中新建域】单选按钮;如果网络中已经存储其他域控制器或林,则选择【现有林】单选按钮,再确定是【向现有域添加域控制器】还是【向现有林中新建域】;(6) 在【命名林根域】向导页中,输入林根域的域名,如:;(7) 在【设置林功能级别】向导页中,选择林功能级别(为限制哪些windows server操作系统可以在此域控制器上运行);(8) 在【设置域功能级别】向导页中,选择域功能级别(不可低于林);(9) 在【其他域控制器选项】向导页中,设置其他信息;(10) 安装向导开始检查DNS配置,打开【Active Directory域服务安装向导】警告框(11) 安装向导开始检查DNS配置,打开【Active Directory域服务安装向导】警告框; 在【数据库、日志文件和SYSVOL的位置】向导页中,指定Active Directory数据库(域中对象的有关信息)、日志文件(存储活动目录与服务的有关服务)和SYSVOL文件夹(操作系统文件的一部分)在服务器上的存储位置;(12) 在【目录服务还原模式的Administrator密码】向导页中,设置在目录服务还原模式(DSRM)下启动此域控制器的密码;(13) 在【摘要】向导页中,显示前面所进行的设置以便用户检查;(14) 在【Active Directory域服务安装向导】警告框中,提示正在根据所设置的选项配置Active Directory;(15) 配置完成;(16) 提示重新启动计算机;(17) 系统已升级为Active Directory域控制器,此时必须使用域用户账号登录,其格式是“域名\用户账户;(18)【Active Directory用户和计算机】窗口注:每一个操作都会给学生发一个PDF格式的操作流程。
Hadoop题库(第1-3-8章)
题库(第一、三、八章)第一章单选题1、大数据的数据量现在已经达到了哪个级别?( C )A、GBB、TBC、PBD、ZB2、2003年,Google公司发表了主要讲解海量数据的可靠存储方法的论文是?( A )A、“The Google File System”B、“MapReduce: Simplified Data Processing on Large Clusters”C、“Bigtable: A Distributed Storage System for Structured Data”D、“The Hadoop File System”3、2004年,Google公司发表了主要讲解海量数据的高效计算方法的论文是?( B )A、“The Google File System”B、“MapReduce: Simplified Data Processing on Large Clusters”C、“Bigtable: A Distributed Storage System for Structured Data”D、“The Hadoop File System”4、2006年,Google公司发表了用来处理海量数据的一种非关系型数据库的论文是?( C )A、“The Google File System”B、“MapReduce: Simplified Data Processing on Large Clusters”C、“Bigtable: A Distributed Storage System for Structured Data”D、“The Hadoop File System”5、对于GFS架构,下面哪个说法是错误的?(A)A、GFS Master节点管理所有的文件系统所有数据块。
B、GFS存储的文件都被分割成固定大小的块,每个块都会被复制到多个块服务器上(可靠性)。
块的冗余度默认为3。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
15.3.1 名称空间的定义策略
• 以为基础,假设想实现如下功能:A::dispA函数中要访问B::num,这要求 B定义在A前,同时,在B中增加dispB函数,其中调用A::dispA()函数,这 要求A定义在B之前,如此看来,上述功能似乎不太可能会实现。 实则不然,这取决于名称空间的定义策略,在前面提及,名称空间中函数 的定义和实现可以分开进行,这是我们解决问题的突破口,见代码15-7。
第15章 名称空间(Namespace)
• 大型程序往往是由团队开发的,即使是个人编写的程序, 随着代码量的增多,变量、函数、类等重名、相互冲突的 现象时有发生,有的情况下,编译器会指明错误所在,但 有时候会发生一些察觉不到的覆盖,让程序员对出现的错 误摸不着头脑。 • 很多厂商也提供了快捷的第3方类库,用户不用关心库中的 类是如何实现的,直到如何调用接口使用即可,但多个厂 商定义的变量、函数和类可能会发生冲突,同样是初始化 操作,甲公司类库提供了initial函数,乙公司可能也提供 了initial函数,如果在程序中同时使用了两个公司的类库, initial函数对应哪个版本呢? • 为了解决这些问题,新的C++标准提供了名称空间机制。旧 标准中(ANSI/ISO 1998)并没有该项机制,所以,一些特 别老的编译器可能并不支持名称空间特性。
15.2 实体的作用域与可见域
• 名称空间可以如中的yaya和abao一样,定义成全 局的,也可以将一个名称空间定义在另一个名称 空间内,形成名称空间的嵌套,但名称空间的定 义不能在代码块内,因此,默认情况下,名称空 间中的实体作用域是全局的。
15.2.1 实体可见域
• 名称空间中实体的作用域是全局的,并不意味着其可见域也是全局的,如 果不使用作用域限定符和using机制,抛开名称空间嵌套和内部屏蔽的情 况,实体的可见域是从实体创建到该名称空间结束(如果有名称空间的嵌 套,则内部名称空间中的实体可能会屏蔽外部名称空间中的实体,这在稍 后会讲到),在名称空间外,该实体是不可见的。 来看一段示例,见代码15-2 。
15.1 什么是名称空间
• 旧的标准中,仅仅依靠名称在程序中的作用域和 可见域来区分同名实体,在第6章中已经介绍了实 体的作用域和可见域的概念,由于“屏蔽”等原 因,可见域一般是作用域的子集。 • 旧标准中使用诸如“#include <iostream.h>”形 式的头文件,而新标准中只要使用“#include <iostream>”即可,旧标准中不需要using指令指 明名称空间,而新标准中需要这样做。
15.3 名称空间的作用域与可见性
• 原则上讲,名称空间的作用域是全局的,但其可 见域却并非如此,而且,不论使用限定符还是使 用using声明语句,都要求名称空间可见,回头看 以下前面给出的代码,就来说,如果将namespace B的定义放在namespace A定义之后,编译器将指 出错误,using语句同样如此,如果在using声明 时,namespace尚未定义,或者说namespace已经 定义,但声明的实体尚未包含在此namespace中, 编译器同样会指出错误,因此,名称空间同样要 先定义、后使用。
15.4 对名称空间的思考
• • • • • • • 下面引用当前流行的名称空间使用指导原则: 使用在已命名的名称空间中声明的变量,而不是使用外部全局变量。 使用已命名的名称空间中声明的变量,而不是静态全局变量。 如果开发了一个函数库或者类库,将其放在一个名称空间中。事实上,C++提倡将标 准函数库放在名称空间std中。 仅将编译指令using作为一种将旧代码转换为名称空间的权宜之计。 对于using 声明,首先将其作用域设置为局部而不是全局。 不要在头文件中使用using编译指令,这样,使得可用名称变得模糊,容易出现二义 性,其次,包含头文件的顺序可能会影响程序的行为,如果非要使用using编译指令, 建议放在所有#include预编译指令后。 名称空间相当于是对在原有名称层次的基础上又扩展了一层,而且是最外面的一层, 原始的名称层次进化规则简单归纳如所示:
• •
15.3.5 未命名的名称空间
• 也可以通过省略名称空间的名称来创建未命名的 名称空间,此时,该无名空间中的实体的可见性 无法扩展(既不能采用“名称空间::实体”的形 式,也不能采用using声明机制扩展),因此,该 实体只能在本空间内使用。 • 在无名空间中创建的全局变量,具有全局生存期, 却只能被本空间内的函数等访问,是static变量 的有效替代手段。
15.2.5 空间内的“屏蔽”
• 在一个空间内,变量作可见域的规则,如内部变量对外部变量的 屏蔽等是和第6章中介绍的内容使一致的,通过一个例子来形象地 说明这一点,见。
15.2.6 先声明,后使用
• • • • • • • • • • • • • • • 和普通变量一样,在使用名称空间中的实体前,必须保证其有效,举例来说,在使用 一个变量前,必须对该变量进行声明。例如,如果将中名称空间A定义修改为: namespace A //创 建名称空间A { void dispA() { int num=3; cout<<"dispA函数中的num: "<<num<<endl; cout<<"A中的num: "<<A::num<<endl; cout<<"B中的num: "<<B::num<<endl; cout<<"外部的num: "<<::num<<endl; } int num=1; //A中声明的num } 编译运行,编译器将给出如下出错信息: error C2039: 'num' : is not a member of 'A'
15.3.3 名称空间嵌套
• 名称空间可以定义在另一个名称空间内,以单层嵌套为例,要访问内部名称空间中的 实体,必须采用“外部名称空间::内部名称空间::实体名”的形式,如果是多层嵌套, 还要多次使用作用域限定符,来看一个简单示例。
15.3.4 using编译指令
• 前面介绍过通过using声明语句使得某个空间中的特定实体可见,using编译指令比using声明更进 一步,通过“using namespace 名称空间名;”的形式,使得名称空间中的实体都可见,不再需要作 用域限定符。 到现在为止,几乎所有示例代码都使用了下述语句: using namespace std;
•
15.5 小结
• 本章探讨了名称空间的用法,这是C++新增加的一 个特性,其目的是为了减少冲突,这在大型程序 组织中十分有效。使用名称空间,关键是掌握空 间中实体的作用域与可见域,以及名称空间的作 用域与可见域的知识,理解其实质,做到知其然, 知其所以然。 • 作用域限定符::、using声明机制和using编译机 制是3种常用的扩展实体可见域的方式,使名称空 间中的特定实体或全部实体在声明可见域内可用。 名称空间内实体的访问规则和原来介绍的没有名 称空间时的情况类似,名称空间还支持嵌套层次 结构,在外部使用内层空间时,必须使用多重作 用域限定符的形式。
15.2.4 using声明带来的多重声明问题(二义性)
• 如果using声明使用不当,很容易引起多重声明错误 (multiple declaration),比如,已经定义了全局函数 disp,却还使用全局using声明语句“using A::disp”,假 设没有屏蔽发生,那么调用disp()时,编译器不确定是全 局函数版本还是A::disp(),引发多重声明错误。 • 变量名同样存在这种问题,假设有两个名称空间A、B中都 定义了int型变量num,在程序的某处需要使用num,如果写 出如下代码: • using A::num; • using B::num; • num=5; • 则最后一句对num的赋值操作具有二义性,因此,应合理使 用using声明机制。
15.1.1 名称空间范例
• 名称空间通过定义一种新的声明区域来创建命名 的名称空间,一个名称空间中的实体不会和另外 一个名称空间中的同名实体冲突,来看一个简单 形象的例子,其既能说明名称空间是怎么回事, 也演示了如何定义全局的名称空间。
15.1.2 定义名称空间
• • • • • • C++中定义名称空间的基本格式为: namespace 名称空间名 { 变量类型 变量; 函数返回类型 函数原型; }
•
15.3.2 推荐用法
• 为了在程序的多个文件中合理使用名称空间,需 要合理组织名称空间的定义,和类定义相似(但 又不同,类定义中成员变量不被创建,而名称空 间中的变量在声明时被创建),一种推荐的做法 是将名称空间的声明接口(仅仅包括函数原型) 放在头文件中,而将变量声明和函数实现放在单 独cpp文件中,这样在使用头文件的地方,只要包 含相应的头文件即可。
•
15.2.2 可见域的扩展
• 在某个名称空间中定义或创建的程序实体,如果要在其他名称空间中或外 部函数中访问,必须使用作用域限定符::或使用using声明机制来使实体 可见,这可看作是作用域的扩展,来看一段示例,对进行修改,见代码 15-3 。
15.2.3 using声明机制
• 如果不希望在每次使用名称空间中实体时都使用 作用域限定符,可使用using声明机制扩展其可见 域,using声明的基本格式为: • using 名称空间::实体名; • 如“using A::dispA()”,至于using声明语句将 该实体的可见域扩展到什么程度,这取决于using 语句的书写位置,换言之,这取决于using语句的 可见域。 • 1. using声明在全局区域 • 2