Visual C++泛型编程实践.docx
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《Visual C++泛型编程实践.docx》由会员分享,可在线阅读,更多相关《Visual C++泛型编程实践.docx(13页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Visual C+泛型编程实践泛型程序设计(Generic Programming) 是建立在C+的Template机制基础上的一种完全不同于面向对象的程序设计思维模式,STL是泛型概念的一套实作产品。Loki是一个与Boost齐名的开放源码的C+程序库,它通过一些精巧的装置为常规C+开发提供了一些很有用的工具。STL非常好用,弹性非常大,效率也很理想。目前几种主流的C+编译器均有相关的STL实现,而个人认为目前非常流行的Visualc+ 6.0平台中开发文档应用程序时,其文档序列化的功能非常好用,但由于其序列化能力建立在MFC之上,并不被STL支持,所以,如何既拥有STL的效率及通用性,又保
2、留MFC的序列化能力,便成了VisualC+ 6.0平台上运用STL技术开发文档应用程序时不得不面对的一个问题,在这里我就以非常流行的Visual C+ 6.0+SP5平台结合一个假定的例子来介绍一下如何在Visual C+6.0中结合使用STL、Loki及模板技术来开发一个文档应用的开发历程,希望能对大家有所启发。示例 先来简单介绍一下我所用到的例子:一个简单的商务进销存基本应用(不必关注细节),它应该包含:职员(Employee)、产品(Product)、仓库(Storage)、往来单位(Supply)、帐户(Account)、单据(Bill)等等,由于每种信息均应有唯一标识,所以我在这里
3、选用STL中的map来表示如下(为了说明简单起见,我们只列两种): std:mapsize,Employee* itsEmployees; /职员表std:mapsize,Product* itsProducts; /产品表. 第一步:实现 我们将以上map放入多(单)文档应用程序的文档类中,很显然,我们必须对每一个表至少提供以下三种最基本的操作:添加新成员函数、删除指定成员函数、获取指定成员函数。 对于添加新成员,我们可以实现如下: size addAccountMember(Account* e); /添加帐户 /获取下一个可用的ID号 size id=getNextAccountID()
4、; itsAccountsid=e; returnid; size addEmployeeMember(Employee* e);/添加职员 /获取下一个可用的ID号 size id=getNextEmployeeID(); itsEmployeesid=e; return id; . 接下来的删除方法仅有一个size(唯一标识)参数,实现如下: void delAccount(size ID); /删除指定帐户 itsAccounts.erase(ID); void delEmployee(size ID); /删除指定职员 itsEmployees.erase(ID); . 获取指定成员的
5、方法如下: Account* getAccountMember(size ID) /获取指定帐户 return itsAccountsID; Employee* getEmployeeMember(size ID) /获取指定职员 return itsEmployeesID; . 另外,我们还要为每一个表提供一个获取下一个可用ID的成员函数: /获取下一个可用职员号Size getNextEmployeeID() if(itsEmployees.empty() return 1; std:mapsize,Employee*:iterator it=itsEmployees.end(); -it
6、; return it-first+1; /获取下一个可用帐户号Size getNextAccountID() if(itsAccounts.empty() return 1; std:mapsize,Account*:iterator it=itsAccounts.end(); -it; return it-first+1; .第二步:分析 以上实现的确达到了我们的设计目的,但仅从直观上来看我就觉得它应该还有改善的空间,最简单的原因:因为它的命名混乱,没有通用性,如: addAccountMember, addEmployeeMember,. delAccount, delEmployee,
7、. getAccountMember, getEmployeeMember,. getNextAccountID, getNextEmployeeID,. 对于同一种功能存在这么多不同名称的函数想起来就让我感到可怕,在我们的这个简单的例子中只对6个表实现了三种功能,我们需要为每个表实现4种不同名称的函数,结果,我们需要记住4*6=24个不同名称的函数及它们所对应的功能,如果,如果我们要对更多的表实现更多的功能.,真的不敢相象我们到底要实现多少个不同名称的函数。我想,不用等到函数接口数量爆炸,我的脑子就先爆炸了。如果能够对同一种功能的函数使用一组相同的名字如: addMember delMemb
8、er getMember getNextMemberID 那么,我们的接口名称数量就只与实现的功能多少成常数关系,而与我们要操作的表的个数无关了,整个程序就应该清晰多了。第三步:改进(重构) 重构是一个最近很流行的程序设计思想,说白了就是对已有程序进行改进,在不改变程序外在行为的前提下对程序结构及设计进行改进,以使程序代码更清晰、程序更健壮、更易于维护。 第一次改进:使用函数重载减少接口名称数量对于添加成员,我们可以直接使用C+的函数重载技术改进如下: size addMember(Account* e); /添加帐户 /获取下一个可用的ID号 size id=getNextAccountID
9、(); itsAccountsid=e; return id; size addMember(Employee* e); /添加帐户 /获取下一个可用的ID号 size id=getNextEmployeeID(); itsEmployeesid=e; return id; 这样一来,消除了对不同表进行操作时调用的函数名称的差异,但我们可以看出,这两个函数的操作逻辑是完全一样的,变化的部分与参数相关,这正是模板技术可以发挥作用的地方,但如何将不同的表添加方法与不同的ID号获取方法及对应的map联系起来呢? 我们再来看删除函数:由于不同表的删除方法均只有一个相同类型的参数size ID,而函数重
10、载必须要有不同的参数列表,所以,要想实现一个void delMember(size ID)分别对应不同的表的删除操作好象是不可能的,getMember(size ID)方法也是一样,它对不同的表操作虽然有不同的返回值,但参数也是一样的,所以,也不能运用C+内的函数重载方法来实现函数接口命名的一致化。而获取下一个可用ID的函数方法甚至连参数都没有,怎么办呢?看来我们没有办法了。 幸运的是,Andrei Alexandrescu在他的 C+设计新思维泛型编程与设计模式之应用一书中为我们提供了一种解决办法: Type2Type它是一个可用于代表参数类型,以让你传递给重载函数的轻量级的ID,其定义如下
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Visual C+泛型编程实践 C+ 编程 实践
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内