首页 理论教育 操作系统实现之路:模拟面向对象思想

操作系统实现之路:模拟面向对象思想

时间:2023-10-21 理论教育 版权反馈
【摘要】:1.使用结构体定义实现对象面向对象开发的一个核心思想就是对象,即把任何可以类型化的东西看做对象,而把程序之间的交互以及调用,以对象之间传递消息的形式来实现。

操作系统实现之路:模拟面向对象思想

虽然在Hello China核心模块的开发中使用的是C语言,但在开发过程中引入了面向对象的编程与开发思想,把整个核心模块分成一系列对象(比如内存管理器对象、核心线程管理器对象、页框管理器对象、对象管理器等)来实现。这样实现起来,独立性更强,而且具备更好的可移植性和可裁剪性。

但C语言本身是面向过程的语言,因此用C语言来进行面向对象的编程,需要对C语言做一些简单的预处理。在Hello China的开发中,我们先预定义了一系列宏,用来实现面向对象的编程机制,另外,针对Hello China的特点,定义了一个对象管理框架,统一管理所有开发过程中的对象。

在Hello China的开发中,我们充分利用C语言的宏定义机制,以及函数指针机制,实现了下列简单的面向对象机制。

1.使用结构体定义实现对象

面向对象开发的一个核心思想就是对象,即把任何可以类型化的东西看做对象,而把程序之间的交互以及调用,以对象之间传递消息(实际上就是对象成员函数的调用)的形式来实现。面向对象的语言(比如C++)专门引入了对象类型定义机制(比如class关键字),C语言中没有专门针对面向对象的思想,也没有引入对象类型定义机制,但C语言中的结构体定义却十分适合定义对象类型(实际上在C++中,struct关键字也用来定义对象类型)。比如在C++中,定义一个对象类型如下:

利用C语言的struct关键字,也可以实现类似的对象定义:

与C++不同的是,C语言定义的成员函数增加了一个额外参数:lpThis,这是最关键的一点。实际上,C++在调用成员函数的时候,也隐含了一个指向自身的参数(this指针),因为C语言不支持这种隐含机制,因此需要明确指定指向自身的参数。

这样就可以定义一个对象:

调用对象的成员函数,在C++里面代码如下:

而在C语言中(参考上述定义),则可以这样:

使用这种思路,我们简单实现了C语言定义对象的基础支撑机制。

2.使用宏定义实现继承

面向对象的另外一个重要思想就是实现继承,而C语言不具备这一点。为了实现这个功能,我们在定义一个对象(结构体)的时候,同时也定义一个宏,比如定义如下对象:

同时,定义如下宏:

假设另外一个对象从该对象继承,则可以这样定义:

这样就实现了对象__CHILD_OBJECT从对象__COMMON_OBJECT继承的目的。

显然,这样做的一个不利之处是对象尺寸会增大(每个对象的定义都包含了指向成员函数的指针),但相对给开发造成的便利以及增强的代码的可移植性而言,是非常值得的。(www.xing528.com)

3.使用强制类型转换实现动态类型

面向对象语言的一个重要特性就是,子类类型的对象可以适应父类类型的所有情况。为实现这个特点,我们充分利用了C语言的强制类型转换机制。比如__CHILD_OBJECT对象从__COMMON_OBJECT对象继承,那么从理论上说,__CHILD_OBJECT可以作为任何参数类型是__COMMON_OBJECT的函数的参数。比如下列函数:

那么,以__CHILD_OBJECT对象作为参数是可以的:

可以看出,上述代码使用了强制的类型转换。

在Hello China的开发中,我们使用强制类型转换实现了对象的多态机制。

4.对象机制

在面向对象的语言(比如C++)中,实现了一系列对象机制,比如对象的构造函数和析构函数等。另外,一些面向对象的编程框架(比如OWL和MFC等)对应用程序创建的每个对象都做了记录和跟踪,这样可以实现对象的合理化管理。

但在C语言中,缺省情况下却没有这种机制。为了实现这种面向对象的机制,在Hello China的开发过程中,根据实际需要建立了一个对象框架来统一管理系统中创建的对象,并提供一种机制对对象创建时的初始化以及销毁时的资源释放做出支持。

在Hello China开发过程中实现的对象机制,主要思路如下:

(1)每个复杂的对象(简单的对象,比如临时使用的简单类型等不包含在内),在声明的时候,都声明两个函数:Initialize和Uninitialize。第一个函数对对象进行初始化,第二个函数对对象的资源进行释放。然后定义一个全局数组,数组内包含了所有对象的初始化函数和反初始化函数

(2)定义一个全局对象,对系统中所有对象进行管理,这个对象的名字是ObjectManager(对象管理器),该对象提供CreateObject、DestroyObject等接口,代码通过调用CreateObject函数创建对象,当对象需要销毁时,调用DestroyObject函数。

第一点很容易实现,只要在声明的时候,额外声明两个函数即可(这两个函数的参数是__COMMON_OBJECT*),声明完成之后,把这两个函数添加到全局数组中(该数组包含了系统定义的所有对象相关信息,比如对象的大小、对象的类型、对象的Initialize和Uninitialize函数等)。

对象管理器ObjectManager则维护了一个全局列表,每创建一个对象,ObjectManager都把新创建的对象插入列表中(实际上是一个以对象类型作为Key的Hash表)。每创建一个对象ObjectManager都申请一块内存(调用KMemAlloc函数),并根据对象类型,找到该对象对应的Initialize函数(通过搜索对象信息数组),然后调用这个函数初始化对象。

对于对象的销毁,ObjectManager则调用对象的Uninitialize函数,这样就实现了对象的自动初始化和对象资源的自动释放。

在Hello China的开发过程中,一直使用这种对象模型。实际上,对象模型不局限于对象的自动初始化和自动销毁,还适用于对象枚举、对象统计等具体功能。比如,为了列举系统中所有的核心线程,可以调用ObjectManager的特定函数,该函数就会列出系统中的所有核心线程对象,因为ObjectManager维护自己创建的所有对象的列表,而核心线程对象就是使用ObjectManager创建的。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈