名字
空间 前面说明了静态成员变量
,它的语义是专用于某个类而又独立于类的实例
,它与全局变量的关键不同就是名字多了个限定符(即“::”,表示从属关系),如A::a是A的静态成员变量,则A::a这个名字就可以表现出a从属于A
。因此为了表现这种从属关系,就需要将变量定义为静态成员变量
。考虑一种情况,映射采矿。但是在陆地上采矿和在海底采矿很明显地不同,那么应该怎么办?映射两个函数,名字分别为MiningOnLand和MiningOnSeabed。好,然后又需要映射在陆地勘探和在海底勘探,怎么办?映射为ProspectOnLand和ProspectOnSeabed。如果又需要映射在陆地钻井和在海底钻井,在陆地爆破和在海底爆破,怎么办?很明显,这里通过名字来表现语义已经显得牵强了,而使用静态成员函数则显得更加不合理,为此C++提供了名字
空间,格式为namespace <名字> { <各声明或定义语句> }。其中的<名字>为定义的名字空间的名字,而<各声明或定义语句>就是多条声明或定义语句。如下:
namespace OnLand { void Mining(); void Prospect(); void ArtesianWell(){} }
namespace OnSeabed { void Mining(); void Prospect(); void ArtesianWell(){} }
void OnLand::Mining() { long a = 0; a++; } void OnLand::Prospect() { long a = 0; a
++; }
void OnSeabed::Mining() { long a = 0; a++; } void OnSeabed::Prospect() { long a =
0; a++; }
上面就定义了6个元素,每个的类型都为void()。注意上面OnLand::ArtesianWell和OnSeabed::ArtesianWell的定义直接写在“{}”中,将是inline函数。这样定义的六个变量它们的名字就带有限定符,能够从名字上体现从属关系,语义表现得比原来更好,OnSeabed::Prospect就表示在海底勘探。注意也可以如下:
namespace A { long b = 0; long a = 0; namespace B { long B = 0; float a = 0.0f } }
namespace C { struct ABC { long a, b, c, d; void ABCD() { a = b = c = d =
12; } } ab; }
namespace D { void ABC(); void ABC() { long a = 0; a++; } extern float bd; }
即名字空间里面可以放任何声明或定义语句,也可以用于修饰自定义结构,因此就可以C::ABC a; a.ABCD();。应注意C++还允许给名字空间别名,比如:namespace AB = C; AB::ABC a; a.ABCD();。这里就给名字空间C另起了个名字AB,就好像之前提过的typedef一样。
还应注意自定义类型的定义的效果和名字空间很像,如struct A { long a; };将生成A::a,和名字空间一样为映射元素的名字加上了限定符,但应该了解到结构A并不是名字空间,即namespace ABC = A;将失败。名字空间就好像所有成员都是静态成员的自定义结构。
为了方便名字空间的使用,C++提供了using关键字,其后面接namespace和名字空间的名字,将把相应名字空间中的所有映射元素复制一份,但是去掉了名字前的所有限定符,并且这些元素的有效区域就在using所在的位置,如:
void main() { { using namespace C; ABC a; a.ABCD(); } ABC b; b.ABCD(); }
上面的ABC b;将失败,因为using namespace C;的有效区域只在前面的“{}”内,出了就无效了,因此应该C::ABC b; b.ABCD();。有什么用?方便书写。因为每次调用OnLand::Prospect时都要写OnLand::,显得有点烦琐,如果知道在某个区域内并不会用到OnSeabed的成员,则可以using namespace OnLand;以减小代码的繁杂度。
注意C++还提供了using更好的使用方式,即只希望去掉名字空间中的某一个映射元素的限定符而不用全部去掉,比如只去掉OnLand::Prospect而其它的保持,则可以:using OnLand::Prospect; Prospect(); Mining();。这里的Mining();将失败,而Prospect();将成功,因为using OnLand::Prospect;只去掉了OnLand::Prospect的限定符。
至此基本上已经说明了C++的大部分内容,只是还剩下模板和异常没有说明(还有自定义类型的操作符重载,出于篇幅,在 《C++从零开始(十七)》中说明),它们带的语义都很少,很大程度上就和switch语句一样,只是一种算法的包装而已。下篇介绍面向对象
编程思想,并给出“世界”的概念以从语义出发来说明如何设计类及类的继承体系