C++面向对象思想(1):类的设计



1.类的功能、来源和应用

类的实质是将计算机系统中的任何软硬件事物皆用数据属性和数据操作聚合的实体表示,概括事物在整体、存储和功能,实例对象创建、子系统构成、所有元素的同一性操作等不同方面的特征,从而在编程的不同阶段为过程、设计模式、应用框架提供功能服务,具有很强的灵活性。

类不仅概括客观世界中一类物质的共性,应用在程序中,并且实现不同程序中的软件复用,例如时钟的共性是显示时间,则时钟类可在任一程序中复用;而且代表软件系统的工作过程,是系统服务功能的提供者。类的这个功能不仅在设计的多个成员函数中获得反映,而且通过组合软件系统组成部分的功能并且设置公有功能接口类实现,例如编译器类compile是接口类,组合scanner算法、语法分析算法和目标代码生成算法三个主要组成部分。

把过程式程序设计的数据结构及操作封装成类,可实现一类对象共享数据结构,在软件工程的角度提高程序内聚性。并且,将序列数据结构元素的获取操作设置成迭代器类iterator,可依次巡访容器类的各个元素,而不必暴露容器集合的内部表述方式,广泛适用各种数据类型的数组、二叉树、图的邻接表等复杂数据结构。遍历算法是对所有元素执行“找到一个元素”的操作,而搜索算法是“找到一个特定的元素”的操作,所以 迭代器iterator具有遍历和搜索的双重特性,C++发展的新成果,称为标准模板库STL(standard template library)技术。

类的设计应考虑在软件系统中的类间关系、类层次,在继承和多态、多继承上类的进化,应用系统与目标结果的关系(例如工厂与产品),类在不同应用环境的演化和移植,还应考虑实例对象在实际应用中呈现的规律性的联系对类的影响,例如一组不同性质和类型的对象的应用结构称为组件。所以,类应管理、组织、创建不同组成部分的复合实例对象和组件,例如图形界面实例对象。

以上三个方面是C++类的设计应考虑的主要内容。在这三个方面中,类的主体分别是客观实在物和软件系统、数据结构或容器vector、关系和设计模式。因此,面向对象技术中的对象(object)不仅是独立的客观世界物质,而且是数据的逻辑结构和物理结构、软件系统和输出结果。软件复用是指程序组件或软件成分不作修改或稍加改动就多次重复使用。软件复用有三个级别:代码重用,设计结果重用(应用框架)和设计模式重用(分析结果重用)。代码重用是最常见和最普遍的,包括源代码剪贴(复制、克隆),源代码包含(头文件)和继承(扩充和具体实现)。后一种类扩展了软件重用的范围,软件系统类是设计结果重用、软件系统和输出结果的模式和实例对象复合是分析结果重用、数据的逻辑结构和物理结构是源代码重用,例如模板和迭代器。

类是客观世界中的物质,也是计算机系统中的软硬件、运行时系统和行为模式的操作和管理,例如内存管理、数据传递方式操作等。类可以是客观存在物,也可以是数据结构实体和容器,以及应用程序所需表示的各种要素间关系和联系,特定应用项目的功能要素,或软件子系统。

类在共性、系统的组成功能、内存及计算机资源管理、对数据结构中元素的操作、算法组合、适应实例对象组件应用及进化等方面都行之有效,因此在编写大型复杂程序、设计模式、STL等方面实现了效率高,可行、可复用的编程方法。并且,C++的类具有系统自动执行的特征,不需要显式调用,可防止程序设计不一致的错误,例如构建函数和析构函数。而应用实例对象的关键技术是数据存储区的分配。对象在初始化、声明赋值、类内赋值与类层次中赋值、多继承赋值、对象引用和指针,以及函数形参传递和返回值等方面都必须处理存储单元的分配、更新和回收,防止越界、内存泄漏、重复分配单元和赋值等错误的发生。

2.类的成员和实现方法

    类是客观物质、编程类、数据结构类、不同类型的vector容器、算法行为模式和软件体系的共性和必要性。类代表了生物世界的进化和多样性。若一个类有更多的继承或多继承,则类的层次将逐渐发展,这表明类的设计能适应不同的应用环境。有些类在客观世界中并不存在,例如当两个类具有很高的相似性时,因此需要建立一个高层次的类,包涵这两个类的相同部分,则此方法建立了类的层次。然而,新的类并不存在,由于编程的需要设置,因此称为编程类。

类是一组属性值上的相关操作构成的整体,因此有功能性和独立性。属性和操作分别称为数据成员和成员函数。属性是一个类区分其他类的主要特征或数据的内部表述方式,操作或方法则是类对外界提供的功能服务或内部机制的实现方法。成员函数是一个模块(package),提供类的一个具体功能,产生特定数据成员或进行操作。

类的定义中包涵的联系有数据成员间的联系,例如迭代器的数据成员定义见下。

class vector{

    int sz;  //已经初始化的元素数量

    double *elem;  //容器元素的首地址

    int space;  //容器存储空间总长度

    public:

      //...

};

 上述实现可由图1表示:

     

vector类中,数据成员szspace是下标,elem是容器第一个元素的地址,实际是数组名,elem[]数组保存初始化的元素。sz=elem[]最后一个元素下标+1(0开始计数),表示elem[]数组的长度,并且为新的元素分配下一个存储单元,实现初始化。space=最后一个存储单元下标+1,可用在vector类向系统申请新的存储单元。若space==sz,表示容器没有空闲的内存,应该申请分配新的存储区。

1可知,vector类是一个连续的存储区。对系统而不是编译器分配的存储区,vector用数据成员space标识存储区总长度,而用elem[]标识已经初始化的元素分配的存储单元构成的数组,sz标识的已分配存储单元长度,space-szvector类的空闲空间存储单元的数量。因此,vector类的三个数据成员的关系是共同刻画容器数据存储区的整体特征和存储结构。在数据结构中,这三个元素可视为邻接表的表头数组,实际是对象的数据存储区。而在操作系统中,elem是基址存储器,sz是长度存储器,space是可变界限存储器,因此可用在指针标示。

类的成员函数与数据成员间的联系是操作数据成员的功能,例如:搜索和遍历所有元素,对数据成员或某一个下标的设值/取数,对全部或部分数据的排序,分析输入数据,数据成员的格式转换(与类型转换不同),计算,显示图元或值等,或者生成数据成员,例如:输出,计算,生成结果的结点等。类的数据成员间的关系和成员函数与数据成员间的联系的相关程度表示类的设计质量。数据成员描述一个数据结构的整体特征,表明成员函数共享数据成员。

类具有封装性,是一个接口和一个实现,具有隐藏内部数据和成员函数的实现细节等内部机制,但是提供功能的公有接口。公有功能接口的用途是指定应用程序使用该类的方法,而内部机制则为功能接口提供实现保障和访问控制。它们保存在不同的文件中,称为接口与实现的分离。

成员函数对数据成员的操作是一种联系,提高程序的内聚性。类的独立性减少应用程序调用的耦合性。组件是一个或多个密切相关的类,能完成对数据成员中的元素进行可重新装载的特定运算符的功能或者一个操作集的复合并且可进行到下一个元素。当C++程序的基本单位是类和组件时,各部分的耦合与关联降低,因此程序是由相对独立的,相互间引用较少的部分组成,降低了软件复杂度,减少了程序出错的次数。软件复杂度包涵输入数据规模,问题域的规模和功能,以及程序实现复杂度。C++程序设计提高了软件工程的管理效率,降低了重用难度,提高了软件生产能力。类的定义中的接口和实现的分离,使得程序修改不传播因数据依赖和一致性要求引发的错误。应用程序的演化将不导致修改类的内部机制,而类和实例对象的升级对外界的影响很小。

类的数据成员和成员函数间的联系和具有公有功能的实体封装,类的封装产生和包装成员的局部相关性,导致类的独立性和层次性;类为用户程序提供资源,可用继承的方式生成派生类,并且多个对象相关而具有普遍法则的应用产生设计模型,因而类成为软件重用的基础单元与合成组件的细胞,实现了程序复用,不仅能通过类的独立性和组件的应用模式降低复杂性,实现大型程序,而且可防止程序修改产生的错误波动

3.类和实例对象的关系

类描述一类事物的本质特征,根据所有实例对象的共性总结,类的数据成员包括属性和其他类的对象,成员函数则是以实例对象和为单位的操作和计算,包括最基本的合法性检查和报告异常与无效。例如雇员类,在一个单位或公司上班有各种不同的职员(employee),可分为产品销售人员、研发人员、骨干员工,还有部门经理(manager)、高级主管(director)、秘书助理,工程师(engineer)、财务人员等,这些职工最基本的属性应有姓名、年龄和工资,设置成员函数则根据应用功能不同而有所不同,然而从管理实例对象的角度看,类的操作有创建、删除、和操作对象,数据成员的组织和存储结构,以及为实例对象设想存储单元的分配方式。然而类的设计并不仅仅是所谓类主体决定的,类必须在软件系统中和其他类“打交道”,称为类间的关系,因此还应有职务、行政级别、学位、职员编号、所在部门、雇佣聘任日期等。因此,类和对象的关系以及类间关系决定类的设计,对象应用模式、结构和算法的总结又产生新的编程类或数据结构类。一个软件系统中所有类的关系可用UML的类图表示,类图中的关系有关联(调用)、组成组合或聚合等。UML是统一建模语言,在面向对象技术设计工具软件中应用最广泛。

对象是类的实例化。在C++程序设计时,根据类间关系,产生对象合作完成一个应用程序。对象的另一个来源是客观物质的应用。  例如,图形程序是对计算机屏幕的图形设计,因此用类描述屏幕,而声明实例对象使用屏幕类编程。或者,对象是一个数据结构整体,对象的功能是对整体和元素的操作。若一个公司有100名各种岗位的职员,则雇员类有100个实例变量,每一个职员的信息将创建一个雇员类的对象,因此实例对象的起始特征是数据成员的初始化。C++程序通过创建的对象间的合作和消息传递完成功能,因此对象以调用成员函数和赋值为主要标志。

类按组管理对象,增加、删除、放置、构建、组织和操作对象或对象的元素,为对象提供成员函数、通用的操作方式和静态数据的共享,将一组对象构成链表或者提供一个数据结构对象的内存管理和元素访问方式。对象实例化是类应用的前提,不仅包括数据成员值初始化,而且包括对象值的更新,可用赋值语句、指针和引用实现,例如实参对成员函数形参的赋值。调用一个对象的成员函数是消息驱动的一个应用类型。类的封装性还要求访问控制,防止数据访问和函数调用越权发生的错误。

 类和对象是真实世界的实体,类的继承和对象复合可实现软件复用中的源代码复用和分析复用,具有高阶的独立性。大型程序在面向对象技术基础上,有效消除了名空间限制和数据耦合及功能耦合,应用程序规模得到扩大,而且更易于修改和调试,程序复杂性和错误都得到控制或减少,软件维护成本下降。

对象实例化有三部分的内容:数据成员的值、成员的访问权限和存储单元的分配、管理与回收。对象的存储单元构成地址空间的处理,例如申请、回收和指针、引用等。实例化是将数据成员的存储单元和初始值赋予类变量,将数据成员的值归并到类中生成一个实例对象,完成类在一个范围或方面的应用,实现类的具体功能。对象数据成员的存储单元相互独立,可防止越界访问。而且设置访问权限又可防止类外的干扰。实例化的概念在静态数据成员上有更清晰的反映,一组对象共享静态数组,分工协作,或者共享数据结构,完成同步任务。

类生成对象的构造、决定对象的功能和应用范围,对象的应用反作用类的定义。类可管理一组对象,或者不同元素类型的对象产生具有模板性质的类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值