一旦一个函数在其参数表中命名一个类型或者在返回一个值时命名一个类型,就称这个函数在其接口中使用了该类型。也就是说,如果类型名是函数返回类型的一部分或者是签名的一部分,就说在这个函数的接口中使用了这个类型。
如果在声明一个函数时涉及某个类型,那么就说在该函数的接口中使用了该类型。
例如,自由函数:
在接口中明显使用了类IntSet。该函数碰巧返回一个int,所以int也将被认为是这个函数接口的一部分。然而,基本类型是普遍存在的,在实践中可以忽略基本类型。
如果一个类的(公共)成员函数的接口中使用了某个类型,那么就说在这个类的(公共)接口中使用了该类型。
在C++中对类的逻辑访问有三个层次:公共的(public)、受保护的(protected)和私有的(private)。一个类的公共接口定义为这个类的所有公共成员函数接口的并集。一个类的受保护的接口在定义上与此类似。换句话说,当类B的一个(公共)成员函数在其接口中使用了类A,我们就说类B在B的(公共)接口中使用了类A。例如,类IntSetIter的构造函数IntSetIter(const IntSet&)在它的接口中使用了类IntSet,因此在IntSetIter的接口中使用了IntSet。
“Uses-In-The-Interface(在接口中使用)”关系是最常见的关系之一,表示为:
也就是说,的意思是“类B在其接口中使用了类A”。我们有时会随意些,说“类B在接口中使用了类A”,但是我们的意思始终是类B在类B的接口中使用了类A,而绝不是类B在类A的接口中使用了类A。
符号可以想象成一个箭头,它的尾部在上,头部不见了(或者想象成正指挥着一个管弦乐队成员的指挥棒)。隐含箭头的方向很重要——它指向隐含依赖的方向。也就是说,如果B使用了A,那么B依赖A,但反之则不然。我们会在3.4节中更多地论述隐含依赖。
图1-18显示了intset组件的逻辑视图,包括在此定义的逻辑实体(类和自由运算符函数)“Uses-In-The-Interface”关系。图中反映出IntSetIter和两个自由运算符都在它们各自的接口中使用了IntSet。
“Uses-The-Interface”关系对逻辑设计和物理设计都是一种颇有价值的工具。将逻辑实体(类和自由运算符)限制在文件作用域内时,这个符号最有用。自由运算符经常会从逻辑图表中省略,以减少符号的混乱。
一个类的实际逻辑接口可能相当大而且复杂。通常我们最大的兴趣在于展现一个内在的依赖关系而不是详细的使用方法。一个类的接口所使用的类型集合,比任何特定成员函数所使用的类型集合都更稳定(即在开发和维护过程中不大可能改变)。所以,被视为一个整体的类的使用特性越抽象,在逻辑接口上的微小改变就越比单个成员函数的使用特性更具有弹性。