[变量命名空间的探讨] 命名空间

  收稿日期:2006-06-30?   作者简介:赵海廷(1948-),男,辽宁盘锦人,武汉科技大学中南分校信息工程学院教授。?   (武汉科技大学中南分校 信息工程学院,湖北 武汉 430223)?
  
  摘 要:变量的命名空间是解决在同一作用域内同名成员引用问题的方法,本文从介绍C++/VC++系统中变量的生存期、作用域、可见性入手,进而讨论变量的命名空间,命名空间成员的直接引用、引入命名空间所有成员和命名空间的别名等应用问题。?
  关键词:生存期;作用域;可见性;命名空间??
  
  1 变量的生存期及其作用域?
  
  变量的生存期讨论的是变量是否存在的问题,而变量的作用域讨论的是在变量存在的前提下的有效范围问题。?
  
  1.1 变量的生存期?
  变量的生存期就是变量从创建到消亡的这段时间。C++/VC++语言的变量的生存期可以分为静态生命期和动态生命期。?
  如果变量的生存期与系统程序的运行期相同,则该变量就具有静态的生存期。在所有大括号对之外定义的变量具有静态生命期。在定义变量时在数据类型之前冠以“static”关键字的外部变量或局部变量也具有静态生存期。?
  在括大号对内定义变量的生存期从变量的定义点开始,结束于定义该变量对应大括号处,该种变量具有动态的生存期。?
  
  1.2 函数原型作用域?
  在变量的生存期间,每个变量都有各自的作用域,在各自的作用域内,该变量可以是可见的,也可以是不可见的。?
  C++系统的变量的作用域可以分为:函数原型作用域,局部作用域,文件作用域、全局作用域和对象族作用域。?
  所谓函数原型作用域就是在函数说明时形式参数的作用范围。例如下面函数说明:
  doubleArea(doubleradius);?
  其中形参radius的作用范围就在Area函数的小括号对内,在程序的其它地方将无法引用该变量,我们说变量radius的作用域就在函数Area函数的原型说明中。?
  
  1.3局部作用域?
  定义在大括号内的变量一般称为局部变量,局部变量的作用域从说明变量处开始,一直到块结束的大括号为止。例如以下函数:?
  在上述函数中,函数fuction的形参a,和本函数内部定义的局部变量b、c的生存期和作用域都是本函数;而变量d的生存期和作用域是从定义点开始,直到包围它的大括号的结束。?
  
  1.4全局作用域和文件作用域?
  在大括号之外定义的变量具有全局的生存期和全局的作用域,这种变量的作用域开始于变量定义点,结束于本文件。若是多文件系统,通过extern说明,还可以在其它文件中引用。?
  如果一个全局变量在定义时其数据类型前面冠以“static”关键字,该变量具有全局的生存期和本文件的作用域,也就是该变量只能在定义它的文件中引用。?
  
  1.5对象族作用域?
  在面向对象的C++系统中,静态成员变量要在类内进行静态变量的说明,在类外进行静态变量的定义。该变量在该类的所有对象间只有一个拷贝,为所有对象共同共享。可以认为静态成员变量对该类族的所有对象具有作用域和可见性。例如下面程序:?
  上述程序的运行结果说明静态成员变量a在各个对象间仅有一个拷贝,其引用的方法可以是“对象名.变量名”,也可以是“类名::变量名”。?
  还有一种说法就是类作用域。所谓的类作用域就是在类内定义的数据成员,在类的内部可以被类的成员函数访问;当创建该类的对象时,该类的数据成员将被克隆到相应的对象中。?
  
  2变量的可见性和作用域分辨?
  
  可见性是指程序运行到某一点,能够被引用的标识符,就说标识符在该处可见。?
  
  2.1不同作用域间的同名覆盖?
  在不同作用域间具有同名的变量,将产生同名覆盖问题。例如下面程序:?
  上述程序的输出为:789,456,123?
  内层大括号对是内层a变量的作用域和可见性范围,同时将屏蔽中层和外层的a变量,使其不可见。在程序的控制流程退出内层大括号对时,内层a变量的存储单元将被释放。程序控制流程进入中层a变量的作用域范围,中层a变量可见并屏蔽外层a变量。?
  
  2.2派生类中同名成员的分辨?
  在类的派生过程中,派生类中若定义了与其父类同名的数据成员或成员函数,在派生类对象下要引用父类的同名成员则需要使用作用域分辨符进行分辨。?
  派生类对象引用父类成员的格式为:“派生类对象名.父类名::成员名”?
  例如下面程序:?
  上述程序的运行结果为:?
  这里是C类的成员函数!这里是A类的成员函数!这里是B类的成员函数!?
  上述例子中只给出了成员函数的引用,对于同名的数据成员也可以如此进行引用。
  
  3命名空间?
  
  为了解决同名成员在一个系统中的引用问题,C++语言在1993年引入了命名空间“Namespace”的概念及其应用方法。?
  在程序中使用命名空间,首先要将通常使用的I/O包含文件“iostream.h”改为“iostream”;其次还要加入“usingnamespacestd;”语句。?
  
  3.1 命名空间的定义方法?
  命名空间定义的格式为:?
  namespace命名空间名{……}?
  上述大括号对内就是一个命名空间。?
  
  3.2 命名空间成员的引用方法?
  命名空间内成员的引用有三种方法:直接引用命名空间的成员,用using声明访问命名空间的成员和引入命名空间的所有成员。?
  3.2.1 直接引用命名空间的成员?
  直接引用命名空间成员的格式为?
  命名空间名::成员名?
  例如下面程序:?
  3.2.2用using声明引用命名空间的成员?
  引用命名空间成员的第二种方法就是使用using声明所引用命名空间的成员。使用using将某个名称引入特定的作用域,这样的名称将不需要作用域限定符限定。如果引用某个函数名,则该命名空间的所有同名的函数都将被引入该作用域。?
  使用using声明访问命名空间成员的格式为:?using? 命名空间名::成员名?
  例如下面程序:?
  程序运行结果为:abcd,A,123.456,2?
  3.2.3引入命名空间的所有成员?
  引用命名空间成员的第三种方法就是引入命名空间的所有成员。将一个命名空间的所有成员引入某个作用域,应用此种方法引入后不需要具体的作用域分辨。?
  变量的生存期表明一个变量是否存在的问题;变量的作用域则是在变量存在的情况下,该变量可以引用的范围;变量的可见性则是在变量存在且在作用域内能否被引用的问题。一个变量存在不一定可见,可见的一定存在。?
  命名空间是解决在一个系统中的多个同名变量的引用问题,三种引用方法可以依情况而定。命名空间的别名则是将一个较长的的命名空间名改为一个较短名字的方法。?
  上述讨论的是变量的问题,一般也适应于对象。?
  
  参考文献?
  [1]郑莉,董渊.C++年程序设计(2)[M].北京:清华大学出版社,2002.?
  [2]严运国,赵海廷.C++程序设计基础[M].北京:科学出版社,2005.?
  [3]赵海廷,严运国.C++程序设计基础导学[M].北京:科学出版社,2006.?
  [4]张莉.C/C++程序设计教程[M].北京:清华大学出版社,2004.?
  [5]赵海廷.C语言程序设计[M].北京:人民邮电出版社,2005.?
  [6]郑阿奇.Visual C++实用教程[M].北京:电子工业出版社,2000.
  
  本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读