设为首页 加入收藏

TOP

6.3.2 实现多态
2013-10-07 13:20:12 来源: 作者: 【 】 浏览:48
Tags:6.3.2 实现

6.3.2  实现多态

怎么能够实现多态呢?当前,动态对象是在入口函数中创建的,而按照现有逻辑,入口函数是不允许修改的。笔者要提供一个机会,让库使用者可以创建动态对象。为此笔者特地有一个规定,所有库使用者必须定义一个宏,以注册自己的驱动类。

  1. REGISTER_DRV_CLASS(DriverName) 

如果不使用子类,则需要定义下面的宏而直接使用基类。

  1. REGISTER_DRV_CLASS_NULL() 

那么这两个宏到底有什么作用呢?要看宏定义了:

  1. // 注册子类  
  2. #define REGISTER_DRV_CLASS(DriverName) \  
  3. DrvClass* GetDrvClass(){\  
  4.     return (DrvClass*)new(NonPagedPool, '10YC') DriverName();\  
  5. }  
  6.  
  7. // 注册基类  
  8. #define REGISTER_DRV_CLASS_NULL()\  
  9. DrvClass* GetDrvClass(){\  
  10.     return  new(NonPagedPool, 'ESAB') UsbBaseClass();\  

两个宏都是为了定义一个名称为GetDrvClass的函数。前者注册驱动类的子类,并在GetDrvClass的实现中动态创建子类对象,在返回时将子类对象的指针转换为基类对象指针;后者则声明直接使用基类,并在GetDrvClass的实现中动态创建一个基类对象,并返回其指针。

调用者不必关心被创建的对象到底是来自基类还是子类,他只要使用在基类中定义的接口就可以了,而借助虚拟函数的运行时绑定策略,即可实现多态。

需要注意的是宏REGISTER_DRV_CLASS(DrvClass),其作用和REGISTER_DRV_ CLASS_NULL()是一样的,都将定义一个GetDrvClass函数。

好戏还要看DriverEntry()函数中的实现,重新修改后的函数代码如下:

  1. NTSTATUS  Driver(DRIVER_OBJECT Driver,  
  2.                 UNICODE_STRING Register)  
  3. {  
  4.   DrvClass* pDriver = GetDrvClass();  
  5.   return pDriver->DriverEntry(Driver, Register);  

真是无与伦比的简洁,它通过GetDrvClass函数实现了多态,并立刻将驱动的实现交付到了pDriver对象的手中,而pDriver可以是基类,也可以是任意一个从基类继承的子类。

实现多态的核心是两个类注册宏,以及在入口函数中对GetDrvClass函数的调用。需要注意的是,如果用户同时定义了两个宏,那么系统就会因为发现两个完全一样的GetDrvClass函数而使编译失败;反之,如果上述两个宏一个都没有定义,那么在链接时,将因为无法找到函数定义而链接失败。

驱动工程UsbBaseClass使用驱动基类直接驱动CY001 USB设备,从SOURCE文件中可以看到,它含有的编译文件为DrvClass.cpp和GetDrvClass.cpp两个文件,前者是基类的定义文件,后者只有一行代码,即REGISTER_DRV_CLASS_NULL()。这是最简单的驱动工程。

驱动工程CY001USBClass使用驱动子类CY001DrvClass驱动CY001 USB设备,从SOURCE文件中可以看到,它依旧包含了DrvClass.cpp文件,此外还包含了若干个子类的实现文件。

所以,读者只要在DrvClass甚至CY001DrvClass类的基础上实现子类化,并注册新的子类,就能够实现功能扩展。

如图6-6所示是本节所讲的多态实现原理图。

 
(点击查看大图)图6-6  多态关系图
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇6.3.1 基类、子类 下一篇图解Visual C++ 2010在说明文件中..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: