第 1 章 OCC 体系结构和基本概念
OCC 是用面向对象方法设计的一个 CAD 基础平台(软件)。为了能从整体
上把握 OCC 的组织情况,也为了方便后续章节的讨论,本章将介绍 OCC 体系
结构和几个基本概念。
1.1 OCC 体系结构
1.1.1 面向对象方法和面向对象的软件工程
在介绍 OCC 体系结构之前,先介绍面向对象方法的概念和什么叫面向对象
的软件工程。
在面向对象的方法出现以前,程序员都采用面向过程的程序设计方法,其中
典型的是结构化程序设计。这种设计的思路是:自顶向下、逐步求精。其程序结
构是按功能划分为若干个基本模块,这些模块形成一个树状结构。各模块间的关
系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种
基本结构组成。其模块化实现的具体方法是使用子程序。结构化程序设计由于采
用了模块分解与功能抽象以及自顶向下、分而治之的方法,从而有效的将一个复
杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护
[2]。这种设计方法的致命缺点是:程序的可重用性差。因为它把数据和处理数据
的过程分离为相互独立的实体,当数据结构改变时,所有相关的处理过程都要进
行相应的修改。
而面向对象的方法将数据及对数据的操作放在一起,作为一个相互依存、不
可分离的整体——对象。对同类型对象抽象出其共性,形成类。类中的大多数数
据,只能用本类的方法进行处理。类通过一个简单的外部接口与外界发生关系,
对象与对象之间通过消息进行通信[2]。这样,程序模块间的关系更为简单,程序
模块的独立性、数据的安全性就有了良好的保障,实现了“高内聚”“低耦合”。
另外,继承与多态性可以大大提高程序的可重用性,使得软件的开发和维护都更
为方便。
面向对象的软件工程是面向对象方法在软件工程领域的全面应用。它包括面
向对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面
向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容[2]。
1.1.2 OCC 的体系结构
整个 OCC 就是用面向对象方法设计出来的一个对象库。之所以用面向对象
方法而不是面向过程方法,是因为用面向对象方法有三个好处。第一,由面向对
象方法抽象的系统结构能映射到数据库结构中,很容易实现程序与数据结构的封
装。第二,面向对象方法从所处理的数据入手,以数据为中心来描述系统,数据相
对于功能而言,具有更强的稳定性,这样设计出的系统模型往往能较好地映射问题
域模型[3]。第三,对象、类、继承性、多态性的引入使用,令面向对象的设计方法
能更好地生产可重用的软件构件和解决软件的复杂性问题。
不过,面向对象的设计方法要求开发人员必须花很大精力去分析对象是什
么,每个对象应该承担什么责任,所有这些对象怎样很好地合作以完成预定的目
标。这样做换来的好处是:提高了目标系统的可重用性,减少了生命周期后续阶
段的工作量和可能犯的错误,提高了软件的可维护性[3]。
用面向对象方法和软件工程思想分析,整个 OCC 由五个模块组成,分别是
基础类模块、建模数据模块、建模算法模块、可视化模块、数据交换模块和应用
程序模块。其中,建模数据模块主要提供二维和三维几何模型的数据结构,也称
数据结构模块。
一个模块主要由一个或几个工具箱构成。当然它也可以包含一些执行体和资
源体等。就结构上看,一个工具箱就是一个共享库(如.so 或.dll 类型的文件)。
每个工具箱由一个或几个包组成。而每个包则由许多类组成,例如,
一个几何包包含点类、线类和圆类等。在同一个包中,不能含有相同名字的两个
类。使用类的时候,类名要以包名作前缀,如 Geom_Circle。
图 2.1 简要说明了包的内容。
图 2.1 包的内容
1.2 基本概念
1.2.1 类和泛化
1、类
OCC 是一个面向对象的软件,与所有面向对象的软件一样,其最基本的软
件成分是类。一个类就是一种数据类型的实现。类有自己的行为(由它的函数提
供的服务)和结构(类的数据结构——用来存储其数据)。
OCC 中所有类按其实现方式可以分三种:普通类、推迟类和通用类。普通
类含有实例方法,可以被直接实例化。而推迟类则不能被实例化。推迟类的作用
在于使一层类共同拥有一种给定的行为,而这些行为的发生取决于普通类(推迟
类的派生类)的实现。通过推迟类的创建,可以保证所有派生自同一推迟类的普
通类拥有相同的继承行为。在 C++中,与推迟类等同的是抽象类。
至于通用类,它提供了一套处理其他数据类型的功能行为。通用类的实例化
需要为它的参数指定类型。通用类的作用与 C++中模板类的作用一样。
2、泛化
这里所谓的泛化,主要是通过通用类的实现来获得的。
通用类分两步实现。首先,对一个通用类进行声明以建立模型。在 CDL
(CASCADE 定义语言)中,通用类被声明为对不确定类型数据项的操作。这里
的数据项就是通用类中的形参。对通用类的形参进行限制,就可以使形参类型成
为普通类的子类。要注意的是:声明一个通用类并没有创建一个新的类类型,而
只是定义了一种适用于几个普通类的通用形式。然后,赋予通用类型信息对该通
用类进行实例化。通用类被实例化时,它的形参类型由实参类型(基本类型或基
本类)替代。实例化结束后,就创建出一个新的类。新类可以由用户在实例化声
明中任意命名。按惯例,通用类的实例名通常由通用类名和实参类型名组成。至
于通用类的名字,只需在其本身名字前添加一个前缀(该通用类所在包的名字)。
例 2.1:
class Array1OfReal instantiates Array1 from TCollection (Real);
这 个 声 明 位 于 TColStd 包 的 一 个 CDL 文 件 中 。 它 定 义 了 一 个 新 的 类
TColStd_Array1OfReal。该类是通用类 TCollection_Array1 的一个实例,并且参
数类型指定为实型。
从具有相同形参类型的相同通用类中,可以实例化出不止一个类。这些实例
化出来的类通过各自的实现来识别。其实在 C++中,它们已经不属于同一类了。
另外,我们不能从通用类中派生类。
在由通用类获得的泛化中,我们经常发现许多类由一个共同的通用类型联系
着。这种现象发生在一种基本结构供给迭代器的时候。在这种情况下,有必要弄
清一件事,那就是由相关通用类构成的团体的确用于同一对象类型的实例化。为
了使这个实例化过程成为一整体,可以将一些通用类声明为内嵌类。这样的通用
类就叫内嵌通用类。
一旦主通用类被实例化,它的内嵌类也将被实例化。内嵌类的实例名由内嵌
类名字和主通用类名字组成,通过“Of”连接。
例 2.2:
class MapOfReal instantiates Map from TCollection (Real,MapRealHasher);
这个声明位于 TColStd 中。它不仅定义了 TColStd_MapOfReal 类,也定义了
TColStd_MapIteratorOfMapOfReal 类(该类是通用类 TCollection_Map 的内嵌类
MapIterator 的一个实例)。内嵌类的实例独立于主类的实例,而决非绑定于它。
作为内嵌类,即使它们本身不是通用类,但是内嵌于通用类,它们也是通用的。
1.2.2 数据类型的分类
数据类型是作为类被实现的。类不仅定义了它的数据结构和基于它的实例的
方法,也声明了该实例的处理方式。
依据处理方式(见图 2.2)的不同, OCC 中所有数据类型可分为两大类:
通过句柄(或引用)处理的数据类型和通过值处理的数据类型。一个通过值处理
的类型变量包含自己的实例;而一个通过句柄处理的类型变量包含一个实例的引
用。
通过值处理的类型首先有基本类型,如布尔类型、字符型、整型、实型等。
通过句柄处理的类型变量,如果它不指向任何对象,那我们就说它是空的。要引
用一个对象,我们就得用它的一个构造函数实例化该对象,如例 2.3。
例 2.3:
Handle(myClass) m = new myClass;
在 OCC 中,句柄是一些特殊类,它们以引用的方式对动态存储对象进行安
全处理。句柄提供了一种引用计算机制,通过这种机制,当对象不被引用时,可
以自动析构对象。
图 2.2 数据类型的两种处理方式
1.2.3 持久化和数据模式
数据模式是应用程序用来存储数据的一种结构,由一些持久类构成。
一个对象若可以被永久存储,则是持久的。持久对象可以被它的创建程序或
其它程序在以后的时间里再次使用。
要 想 使 一 个 对 象 在 CDL 中 是 持 久 的 , 必 须 声 明 它 的 类 型 继 承 自
Standard_Persistent 类或其派生类。所有继承自 Standard_Persistent 类的类都是通
过引用处理的。
对于由 Standard_Storable 类派生出的所有类,它们的实例(对象)是不能被
单独存储的,但是可以作为持久对象的区域被存储。所有继承自 Standard_Storable
类的类,其对象都是通过值处理的。
1.3 本章小结
本章用面向对象方法和软件工程思想从整体上分析了 OCC 的体系结构。整
个 OCC 包含五个模块;模块中包含工具箱;工具箱中包含包;包中包含类;类
是 OCC 软件的最基本要素。
本章还介绍了 OCC 的几个基本概念:类、泛化、数据类型的分类、持久化
和数据模式。与 C++类的命名不同,OCC 有自己的命名方法。OCC 中类分为普
通类、推迟类和通用类三种,分别对应 C++中的具体类、抽象类和模板类。OCC
的数据可以分为句柄处理类型和值处理类型两种。OCC 的持久化和数据模式与
一般软件的原理相同,不同的是:为了使对象持久化,需要声明该对象是由
Standard_Persistent 类或其派生类派生的。
第 2 章 基础类分析
顾名思义,基础类是 OCC 的基石。它提供了大量的通用服务,如自动动态
内存管理(通过句柄对对象进行处理)、集合容器、异常处理、通过向下抛掷和
创建插件程序而获得的泛化等。因此,本章将先对 OCC 的基础类模块进行概述,
然后论述其中几个重点部分,如数据类型、集合容器等。
2.1 基础类概述
基础类包括根类组件、串类组件、集合容器组件、标准对象的集合容器组件、
向量和矩阵类组件、基本几何类型组件、常用数学算法组件、异常类组件、数量
类组件和应用程序服务组件。
1、根类组件
根类是基本的数据类型和类,其它所有类都是依此而建立的。它提供以下类
型和类:
(1)基本类型,如 Boolean(布尔类型)、Character(字符型)、Integer(整
型)或者 Real(实型)等。
(2)动态对象的安全处理,以确保那些不再被引用的对象能被及时删除(详
见 Standard_Transient 类)。
(3)可设置的内存优化管理器。它能改善那些经常使用动态对象的程序性
能。
(4)run-time 类型信息扩展机制。它使得复杂程序的创建变得更为简易。
(5)异常管理。
(6)C++各种流的封装。
根类主要在 Standard 和 MMgt 两个包中实现。
2、串类组件
串类用来处理动态大小的 ASCII 和 Unicode 字符序列,可以通过句柄处理,
因此也可以被共享。串类在 TCollection 包中实现。
3、集合容器组件
集合容器是处理动态大小的数据集合的类。集合容器是通用的,即每一种集
合容器定义了一种结构和一些算法,可持有许多对象——通常这些对象不必从根
类继承。这与 C++模板相似。如果需要使用一个给定对象类型的集合容器,则必
须对这个元素的指定类型进行实例化。一旦这个实例声明被编译,所有基于这个
通用集合容器的函数都可以在集合容器对象中实现。
集合容器包含许多通用类,如 run-time 大小的数组、列表、栈、队列、集(Set)
和散列图(hash map)。
集合容器在 TCollection 和 NCollection 包中实现。
4、标准对象的集合容器组件
TColStd 包为 TCollection 包中通用类的一些经常使用的实例化提供对象(来
自 Standard 包)或者串(来自 TCollection 包)。
5、向量和矩阵类组件
向量和矩阵类提供了有关向量和矩阵的常用数学算法和基本运算(加、乘、
转置、求逆等)。
6、基本几何类型组件
基本几何类型提供了基本几何实体和代数实体的实现。这些实现符合 STEP
(Standard Exchange of Product data model,即产品数据模型的交换标准)。它们提
供基本几何 Shape 的描述(点、向量、直线、圆与圆锥、平面与基本曲面、通过
坐标轴或坐标系使 Shape 在平面上或空间中定位)和 Shape 几何变换的定义与应
用(平移、旋转、对称、缩放、复合变换、代数计算工具)。
7、常用数学算法组件
常用数学算法为那些经常使用的数学算法提供 C++实现。这些算法有:
(1)求解线性代数方程组的算法 ;
(2)求一元或多元函数最小值的算法;
(3)求解非线性方程或非线性方程组的算法;
(4)求矩阵特征值和特征向量的算法。
8、异常类组件
OCC 提供了一套异常类。所有异常类都是基于它们的根类—— Failure 类
的。异常类描述了函数运行期间可能发生的异常情况。发生异常时,程序将不能
正常运行。对这种情况的响应称为异常处理。
9、数量类组件
数量类为日期和时间信息提供支持,同时也为表示常用物理量的基本类型
(如长度、面积、体积、质量、密度、重量、温度和压力等)提供支持。
10、应用服务组件
应用服务组件包括几种低级服务的实现。借助 OCC 平台,这些服务可以使