不要重复发明轮子:C++重用的5重境界(4)——继承接口DLL

第四重境界:继承接口DLL

看起来“代理接口DLL”已经能够很好的完成任务了,但追求完美的你是否总觉得有的地方不够优美呢?

关键就在于这部分:

InterfaceClass:: Function1(int param1, char param2 ){

    return m_pRealizeClass-> Function1(param1, param2 );

}

以上这段代码是代理模式的一种实现方法,但也有它的不足之处:对于RealizeClass的函数,InterfaceClass都要写一个函数,每个函数的写法都是一样的:

return m_pRealizeClass-> FunctionXXX(param1, param2 ……………..);

对于只有几个方法的类来说,这可能没有什么,但是如果RealizeClass类有几十上百个方法,那InterfaceClass就有几十上百个这样类似的函数,看起来是不是很晕呢?

 

有没有一种方法能够不用写这么多的无聊的函数呢?有,这就是本章要介绍的“继承接口DLL”。我们还是按照第三重境界的方法来解释这个方法:

继承:就是面向对象的继承概念

接口:就是Java中的Interface一个概念;

DLL:就是动态链接库了:)

翻译成一句话就是:DLL通过继承的方法对外提供接口

 

如果你还记得第三重境界的实现方式,一对比就会发现,这两个方法其实大同小异,关键就是具体的实现方式不一样:一个通过代理模式,一个通过继承方式。那么我们就来看看这个继承方式具体如何实现。

/*******************************DLL代码声明部分开始**********************/

class InterfaceClass{    //声明接口类,无成员数据,只有方法,这里不用dllexport声明,//为什么呢,请自行查阅相关资料?

    public:

    void Function1(int param1, char param2 ) = 0 //声明为纯虚函数,子类必须改写;

    void Function2(int param1 = 0 ;

    void Function3(bool param1, char param2 ) = 0 ;

}

 

class RealizeClass::public InterfaceClass{ //继承接口类,函数必须改写

       //成员变量

       …………………………………..

       //继承的函数,需要重写。

    public:

    void Function1(int param1, char param2 );

    void Function2(int param1 );

    void Function3(bool param1, char param2 ) ;

}

 

//这两个函数是“继承接口DLL”实现关键,后面介绍为什么。

extern InterfaceClass* g_InterfaceClassPtr ; //不要和下面的extern混淆哈:)

extern “C” InterfaceClass* __decspec(dllexport)  CreateInterfaceClass();

extern “C” InterfaceClass* __decspec(dllexport)  DeleteInterfaceClass();

/******************************* DLL代码声明部分结束**********************/

 

/*******************************DLL代码定义部分开始**********************/

void RealizeClass::Function1(){

       //函数具体实现,do what you want!!!

    ……………………………..

}

 

void RealizeClass::Function2(){

       //函数具体实现,do what you want!!!

    ……………………………..

}

 

void RealizeClass::Function3(){

       //函数具体实现,do what you want!!!

    ……………………………..

}

 

InterfaceClass* g_InterfaceClassPtr = NULL;

 

InterfaceClass* CreateInterfaceClass(){

   if(g_InterfaceClassPtr == NULL){

       g_InterfaceClassPtr = new RealizeClass(); //生成的是具体的类

}

 

return g_InterfaceClassPtr;

}

 

InterfaceClass* DeleteInterfaceClass(){

     delete g_InterfaceClassPtr;

     g_InterfaceClassPtr = NULL;

}

 

/*******************************DLL代码定义部分结束**********************/

 

 

/***************************使用DLL的客户端代码********************/

InterfaceClass* pInterfaceClass = CreateInterfaceClass();

pInterfaceClass->Function1(param1, param2);

………………………………………………………

DeleteInterfaceClass();

/***************************使用DLL的客户端代码********************/

 

样例代码到这里就结束了,我们来总结一下这种方法的关键实现点:

1)实现类继承接口类,而不是“代理接口DLL”中的接口类包含实现类的指针(UML中的聚合Aggregation的一种实现方式);

2)由于第一条的存在,使得客户端不能直接new某个对象,所以要通过CreateInterfaceClass来创建一个具体的实现类。

3)由于第二条创建了实现类,为了避免内存泄漏,所以要DeleteInterfaceClass。

 

 ========未完待续,后面更精彩===========

 

时间: 2024-11-04 03:16:24

不要重复发明轮子:C++重用的5重境界(4)——继承接口DLL的相关文章

不要重复发明轮子:C++重用的5重境界(3)——代理接口DLL

第三重境界:代理接口DLL 看到这个名字,可能大家有点迷糊:代理?接口?DLL?三个风马牛不相及的东东扯到一块是什么意思呢? 其实只要按照字面意思就能够大概理解: 代理:就是设计模式中的代理模式: 接口:就是Java中的Interface一个概念: DLL:就是动态链接库了:) 翻译成一句完整的话就是:DLL通过代理模式对外提供接口.   下面我们看看这个"代理接口DLL"是如何实现的. /*******************************DLL代码************

不要重复发明轮子:C++重用的5重境界(1)——代码重用

软件领域有一个著名的描述软件重用的谚语:不要重复发明轮子! 这个道理是很简单,也很明白的,谁都不想重复无用的劳动,但具体实践中我们该如何避免重复发明轮子呢? 各位注意了,谚语中是说"重复发明",不是说"重复使用",也就是说我们实践中其实也是避免不了重复使用轮子的,因此实践中我们的对策也可以用一句简单的语句表达:发明能够重复使用的轮子! 下面我们就以C++语言为例,看看究竟如何"发明重复使用的轮子".   第一重境界:代码重用 最简单的当然就是代码

不要重复发明轮子:C++重用的5重境界(5)——消息通信(完结篇)

  第五重境界:消息通信 话说当年明教教主在连乾坤大挪移的时候,实际上并没有所谓的第7重,这第7重只是创始人凭借着自己的聪明才智想出来的,根本无法证实是否正确,幸好张无忌没有练才躲过一劫. 其实我们这里的所谓第5重也是我凭空想出来的:)大家接下来也可以看到,这一重境界其实和C++或者DLL完全没有关系,但这一重境界绝对不是凭空乱想,而且也绝对不是无法证实的,这一重境界是每个IT人都知道的,也许是每个人进入IT界接触的第一个重用方法--消息通信. aha,是不是觉得很简单.很普通.很傻很天真?!!

不要重复发明轮子:C++重用的5重境界(2)——简单DLL

  第二重境界:简单DLL 稍有经验的人都知道,要解决代码重用的问题其实已经有简单的方法了,那就是动态链接库(Windows平台是DLL,Linux/UNIX是so,下面以DLL为例说明). 简单的DLL实现如下:将对象.方法的定义放在DLL里面,使用时只需要包含DLL的头文件即可. 这样简单的一个设计,就能够解决代码重用的一个大问题:一份DLL只占一份磁盘空间.一份内存空间. 但为什么我没有说解决了另外一个大问题--编译的问题呢? 乍一看好像是解决了编译的问题,例如我修改函数体内的某个执行语句

asp.net forms身份验证,避免重复造轮子_实用技巧

问题:大家都说使用 forms 验证无法得到当前登录用户除了用户名之外的更多信息,经过我的一番小试验,在 forms 方式下自带的 userdata 可以为我们施展天地的地方.下面记录一下我的操作步骤备忘. step 1: web.config 配置关键地方: web.config配置 复制代码 代码如下: <!-- 通过 <authentication> 节可以配置 ASP.NET 用来 识别进入用户的 安全身份验证模式. --> <authentication mode=

解放日报:中国发明界何以“冰火两重天”?

中国第二届专利周日前在内蒙古呼和浩特地区举行.令人意外的是,热热闹闹开场的专利项目推介会现场却冷冷清清,由全国157家单位和个人推荐的306项国家专利项目少有企业问津,听众寥寥无几的场面让"发明家的聚会"变得异常尴尬. 其实,发明家"独舞"的事件已经不是第一次出现了,专利成果转化难的问题如今在全国范围内都是件令人头痛的事.相关数据显示,去年国家知识产权局共受理专利申请69万多件,比上年增长21%.我国去年专利合作条约申请达到5456件, 同比增长38%,增速居世界各

玩玩Spring之Rod Johnson与轮子理论

(本故事除了部分点明道姓并具有故事详细发生的具体时间点地等部分情节以外,其它内容纯属虚构,若有雷同,纯属巧合.) 知道Spring却不知道Rod Johnson的人,好比宇宙中知道社会中义新中国却不知道毛泽东的人一样可笑. Rod Johnson 是Spring Framework的创建者,也是Java和J2EE领域中的知名专家.Rod是 Interface21公司的CEO,该公司是一家致力于提供专业级J2EE和Spring Framework服务的顾问公司. 谈到Rod Johnson,除了S

技术流|使用开源项目的正确姿势:如果没有你要的轮子,那就重新造吧!

软件开发领域有一个流行的原则:DRY,Don't  repeat  yourself.   我们翻译过来更形象通俗:不要重复造轮子.   开源项目主要目的是共享,其实就是为了让大家不要重复造轮子,尤其是在互联网这样一个快速发展的领域,速度就是生命,引入开源项目,可以节省大量的人力和时间,大大加快业务的发展速度,何乐而不为呢?   然而现实往往没有那么美好,开源项目虽然节省了大量的人力和时间,但带来的问题也不少,相信绝大部分同学都踩过开源软件的坑,小的影响可能是宕机半小时,大的问题可能是丢失几十万

java-工具-轮子

几乎每个程序员都知道要"避免重复发明轮子"的道理--尽可能使用那些优秀的第三方框架或库,但当真正进入开发时,我却经常发现他们有时并不知道那些轮子在哪里.最近,我在业余时间带几个年轻的程序员一起做了一个很小的商业项目,而在一起开发的过程中,我几乎在所有需要判断字符串是否为空的地方,看到了下面的代码: if(inputString == null || inputString.length == 0){......} 除了字符串判断是否为空之外,还有很多字符串处理或其他数据类型判断的方法,