一种基于模块的类实现

时间:2022-08-19 02:10:10

摘要:在面向对象编程中类是对象的集合体,实现封装的关键。针对面向对象语言和C语言的优缺点,通过对C语言支持模块编程特性的讨论,提出一种用C语言文件来实现面向对象中类的特性的方法,使面向对象技术应用在资源紧张的环境中。通过实例表明程序具有较高的执行效率,并且保持良好的可维护性。

关键词:面向对象;类;模块;结构体;C

中图分类号:TP312文献标识码:A文章编号:1009-3044(2008)34-1670-03

Implementation of Class Based on Module

XU Bao-lei, HE Xian-bo

(Computer College, China West Normal University, Nanchong 637002, China)

Abstract: In the Object-Oriented, the class is the aggregation of objects, the key of implementing the encapsulation. According an advantage of Object-Oriented technique and C language, through discuss the support of the C language to module programme, put forward a kind of method of characteristic which implementation the class in the Object-Oriented with the C language. Make the problem has heigher executive efficiency, and keeps the high maintainability. Giving some codes to explain how it implementation.

Key words: Object-Oriented; class; module; struct; C

1 引言

对于复杂的嵌入式软件项目,C++所体现的面向对象的分析和设计方法和消息模型驱动的软件开发过程能够显著提高开发效率以及项目的可管理性和可维护性;但是C++语言本身对系统资源的要求高,使得在许多情况下不能直接用来开发嵌入式系统软件。而C++是从C语言发展而来,是C的扩展集,因此使用C语言进行程序设计实现C++面向对象的思想不失为一个很好的选择。

2 对象式与过程式比较

对象式程序设计是一种以数据为中心,基于数据抽象的程序设计范型[1]。一个面向对象程序由一些对象构成,对象是由一些数据及可施于这些数据的操作所构成的封装体。对象的特证由相应的类来描述,一个类可以从其他类继承。面向对象的执行过程体现为各个对象之间相互发送和处理消息。面向对象程序设计可描述为:程序=对象/类+…对象/类=数据+操作。面向对象程序设计有着众多优点:采用数据抽象,以数据为中心把数据及能对其实施的操作作为一个整体(对象)来描述,加强了对数据的保护;可靠性高,所开发的程序更健壮,有较高的安全性检查;可重用性高,在应用程序中采用类库,缩短了开发时间;继承和数据封装使得应用程序的修改带来的影响更加局部化,应用程序更易于维护。而其固有的缺点就是CPU时间的开销,在实际应用中,C++的实现可能比用FORTRAN写的相同的应用程序慢25%以上[2]。

过程式程序设计是以功能为中心,基于功能分解的程序设计范型[1]。过程式程序的执行过程体现为一系列的子程序调用。过程式程序设计可描述为:程序=算法+数据结构,算法是数据加工步骤的描述,而数据结构是对要加工的数据的描述。C语言是一种面向过程的结构化编程语言,既有高级语言易于开发的特点又具有低级语言效率高的优点:C语言程序效率比较高,包括执行速度快和占用空间少;又具有低级语言才具有的一些描述能力,如数据位操作和内存地址操作,容易与汇编语言结合直接操作硬件;因此广泛使用于操作系统等系统软件的实现。但是C语言与面向对象语言C++相比在开发阶段有许多缺点:过程式语言采用的是过程抽象,它对数据和操作的描述是分离的,数据处于附属地位,独立于操作,在程序调用中作为参数传递给子程序,不利于程序的设计、理解何维护;采用过程式封装,即仅对数据操作的封装,缺乏对数据的保护;编程结构不优越,子程序功能的变化会导致程序结构的变化,从而是程序难以复用。

3 模块设计方法

面向对象的程序设计方法起源于信息隐藏和抽象数据类型概念,其设计灵魂就是使用类中的private成员变量隐藏类实现,使用public成员变量暴露类接口,类实现了面向对象中封装的特性,这使得类的设计成为实现面向对象方法的关键。

在C++中,类的定义包括声明和实现两个部分[3]。声明部分包括class语句,它确定了类的属性和行为。当在程序中使用类创建对象时,仅仅是类的公共成员对程序可见,同时隐藏私有成员,程序必须通过公共成员函数间接的访问私有成员。

在软件开发中,通常是利用C语言的结构体(struct)来模拟类实现封装[4],在C语言的结构中定义一些函数指针成员,在结构体初始化时,使他们各自指向所代表的函数,将数据与处理函数绑定在一起。但结构体和C++中的类并非严格意义上的同义词,其区别在于,结构体的成员默认是公有的,而类的成员默认的是私有的[5]。而且结构体只能封装数据(成员变量),操作(成员函数)常常是定义成全局变量,但是无限制的全局变量通常会有害于程序的可读性和可维护性。对此我们可以利用C语言支持模块式的编程风格把单个面向对象的C++程序转变为多个C语言文件来实现封装。C语言提供typedef保留字用于定义新的数据类型,同样可以用它来模仿类的概念,以结构类型实现数据和方法的封装[6]。通常,模块一经别的程序单元引用,当中的数据和例程就可访问了。从这个意义上说,模块类似于C++中的类,是用来模拟面向对象程序设计主要特性的基础框架[7]。

对程序的逻辑单元进行分组体现了程序设计中模块的概念,一个模块通常由一组功能相关(共同实现一个逻辑功能)的程序实体的定义组成,按照“高内聚、低耦合”原则划分模块。在C语言中一个模块可以分为“实现”和“接口”两部分[8],“接口”部分主要指.h头文件,用于定义本模块使用的数据结构或函数以及任何使用该模块的程序之间的接口;“实现”部分主要指C程序的源文件,包含了所有函数的代码,用于具体实现。

在C语言中关键字extern和static可以限定函数或变量的作用范围,具体如表1所示。

static可以实现一定的信息隐藏,达到封装的目的。用extern关键字可以引用外部变量,实现对外部数据的引用。基于这种特性我们在C语言中创建“基于模块”的类来实现面向对象中类的特性,把一个大的面向对象的程序转换成多个清晰定义的“类”文件和“实现”文件,如图1所示。

模块的头文件等价于类的接口,包含导出到其它模块的数据和子程序,并且加强类型安全检查。

参考以下的原则进行设计头文件和实现文件:

.h头文件中不能有数据的定义和可执行代码,只能有宏、类型(typedef, struct, union, menu),数据和函数的声明。使用C语言的关键字static来确保只有本模块中的函数才能访问这个数据,此模块变成了我们的“类”,且模块中static类型的数据成为类的私有数据成员,该模块中的函数就成为模块类的成员函数(公用)。“公有”成员函数在.h文件中定义它们的原型[9]。

“私有”成员函数(该函数只能被在某个特殊模块内定义的函数调用),只需通过在.c实现文件中包含某个类的函数原型即可。“私有”成员函数用关键字static在.c实现文件中有它的原型。

#include预处理指令来手工导入类的头文件,使得文件中的函数可以访问封装在另一个文件中该数据对象,是继承和重入的一种弱形式。#include指令由于具有传递的特性使得程序容易形成循环依赖,所以要使用#ifndef语句来判断。

4 简单实例代码

以下面的模块为例,介绍“基于模块的类”的设计。模块定义了一个date(时间)类,包括属性以及对属性的操作,在这里我们只关注代码的结构。

.h头文件,包括数据抽象类型date以及对其操作的定义。

/* date.h */

static int month;

static int day;

static int year;

/*下面是date的“成员”函数*/

void setdate(int,int,int,int,int,int);

int getdate(int,int,int);

.c实现文件,定义了函数的具体实现;

/* plant.c */

#include<stdio.h>

#include "date.h"

extern void setdate(int m,int d,int y,int month,int day,int year)

{ month=m;

day=d;

year=y;

}

extern int getdate(int month,int day,int year)

{ return year;}

main.c函数,主要是调用类模块,并且测试时间时使用,模块的调用者,

#include<stdio.h>

/*<time.h>、<math.h>库是用来测试程序运行时间的;*/

#include <time.h>

#include <math.h>

#include"date.h" //定义的类;

int main()

{int i=0; // 循环测试次数i;

int m=5;

int d=8;

int y=2008;

//定义两个long类型的变量,放置时间;

long start,end;

start = clock();// 开始时间;

for(i=0;i<10000;i++)

{ void assigndate(m,d,y,month,day,year);

int result=getdate(month,day,year);

printf("Employee hire data %d\n",result);

}

end = clock();// 结束时间;

printf("%ld\n",end-start);//单位:毫秒

return 0;

}

模块对应的c++实现文件为:

//类定义,定义一个date类,

class Date

{public:

Date();

void setDate(int,int,int);

int getDate();

private:

int month;

int day;

int year;

};

Date::Date()

{ month="";

day="";

year="";

}

void Date::setDate(int m,int d,int y)

{ month=m;

day=d;

year=y;

}

int Date::getDate()

{ return year; }

/* data.cpp */

#include<iostream>

#include<cstdio>

#include<iostream>

using namespace std;

#include "date.h"

#include <time.h>

#include <math.h>

int main()

{ long start,end;

start = clock();

int i=0; // 循环测试次数i;

for(i=0;i<10000;i++)

{

Date dateobj;

int hiremonth="May";

int hireday="Eight";

int hireyear="2008";

dateobj.setDate(hiremonth,hireday,hireyear);

cout<<"Enployee hire data"<<endl;

cout<<dateobj.getDate()<<endl;

}

end = clock();

printf("%ld\n",end-start);//单位:毫秒

return 0;

}

图2是对上面程序的测试比较,其中i是循环的次数,测试时间的单位是毫秒。

5 结束语

面向对象的思想已经在C语言中得到了广泛的利用,例如MiniGUI图形支持系统99%以上的代码是C代码,为了保证具有良好的灵活性和可扩展性,MiniGUI的开发中使用了许多面向对象的技术。用模块实现类的方法更适合于系统资源紧张且与硬件紧密相关的嵌入式系统底层软件开发中,利用了过程式语言和面向对象语言的各自优点,保证了程序的高效性简洁性和可维护性,析取硬件相关性与系统特定代码并把它们封装到简单的低层次模块中,并创建访问接口。而且使用模块化和面向对象的设计方法比用常规的程序设计方法能够使软件开发的生产率提高10~100倍[10]。

参考文献

[1] 陈家俊,郑滔.C++语言及面向对象程序设计[M].北京:机械工业出版社,2005:10-12

[2] Stroustrup B.The Design of C++[M].Stanford CA,University Video Communications,1999.

[3] Diane Z.C++编程导论[M].2版.马良荔,赵羽中,程远国,译.北京:电子工业出版社,2005:322-324.

[4] 覃章健,葛良全.C++语言教学中类的本质深入剖析[J].现代计算机,2008(275).

[5] Joyener L.对象揭密:Java、Eiffel和C++[M].鲍志云,译.北京:人民邮电出版社,2003:60-78

[6] 钱亚冠.Linux内核中面向对象思想的研究与应用[J].浙江科技学院学报,2006,18(2).

[7] 毕苏萍,周振红.Fortran与C/C++共享模块中的数据和例程[J].郑州大学学报:工学版,2008,29(1):99.

[8] Oualline S.实用C语言编程[M].3版.郭大海,译.北京:中国电力出版社,2000:350-363.

[9] Pont M J.C语言嵌入式系统开发[M].陈继辉,译.北京:中国电力出版社,2003:81-89.

[10] Deitel H M,Deitel P J.C++程序设计教程[M].薛万鹏,译.北京:机械工业出版社,2000:26-193.

上一篇:RFID技术在载货车辆称重系统的应用及安全性分... 下一篇:模式识别及其在刑事科学技术中的应用