Chinaunix首页 | 论坛 | 博客
  • 博客访问: 14523720
  • 博文数量: 5645
  • 博客积分: 9880
  • 博客等级: 中将
  • 技术积分: 68081
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-28 13:35
文章分类

全部博文(5645)

文章存档

2008年(5645)

我的朋友

分类:

2008-04-28 21:28:50

下载本文示例代码
  泛型程序设计(Generic Programming) 是建立在C 的Template机制基础上的一种完全不同于面向对象的程序设计思维模式,STL是泛型概念的一套实作产品。Loki是一个与Boost齐名的开放源码的C 程序库,它通过一些精巧的装置为常规C 开发提供了一些很有用的工具。STL非常好用,弹性非常大,效率也很理想。目前几种主流的C 编译器均有相关的STL实现,而个人认为目前非常流行的Visual c 6.0平台中开发文档应用程序时,其文档序列化的功能非常好用,但由于其序列化能力建立在MFC之上,并不被STL支持,所以,如何既拥有STL的效率及通用性,又保留MFC的序列化能力,便成了Visual C 6.0平台上运用STL技术开发文档应用程序时不得不面对的一个问题,在这里我就以非常流行的Visual C 6.0 SP5平台结合一个假定的例子来介绍一下如何在Visual C 6.0中结合使用STL、Loki及模板技术来开发一个文档应用的开发历程,希望能对大家有所启发。  示例  先来简单介绍一下我所用到的例子:一个简单的商务进销存基本应用(不必关注细节),它应该包含:职员(Employee)、产品(Product)、仓库(Storage)、往来单位(Supply)、帐户(Account)、单据(Bill)等等,由于每种信息均应有唯一标识,所以我在这里选用STL中的map来表示如下(为了说明简单起见,我们只列两种): std::map<size,Employee*> itsEmployees; //职员表std::map<size,Product*> itsProducts; //产品表..   第一步:实现  我们将以上map放入多(单)文档应用程序的文档类中,很显然,我们必须对每一个表至少提供以下三种最基本的操作:添加新成员函数、删除指定成员函数、获取指定成员函数。  对于添加新成员,我们可以实现如下: size addAccountMember(Account* e); //添加帐户{  //获取下一个可用的ID号 size id=getNextAccountID();  itsAccounts[id]=e;  return id; }size addEmployeeMember(Employee* e);//添加职员{  //获取下一个可用的ID号 size id=getNextEmployeeID();  itsEmployees[id]=e;  return id; } ..   接下来的删除方法仅有一个size(唯一标识)参数,实现如下: void delAccount(size ID); //删除指定帐户{ itsAccounts.erase(ID); }void delEmployee(size ID); //删除指定职员{ itsEmployees.erase(ID); }..  获取指定成员的方法如下: Account* getAccountMember(size ID) //获取指定帐户{ return itsAccounts[ID]; } Employee* getEmployeeMember(size ID) //获取指定职员{ return itsEmployees[ID]; } ..   另外,我们还要为每一个表提供一个获取下一个可用ID的成员函数: //获取下一个可用职员号Size getNextEmployeeID() {  if (itsEmployees.empty())   return 1;  std::map<size,Employee*>::iterator it=itsEmployees.end(); --it;  return it->first 1; }//获取下一个可用帐户号Size getNextAccountID() {  if (itsAccounts.empty())  return 1;  std::map<size,Account*>::iterator it=itsAccounts.end();  --it;  return it->first 1; }..  第二步:分析  以上实现的确达到了我们的设计目的,但仅从直观上来看我就觉得它应该还有改善的空间,最简单的原因:因为它的命名混乱,没有通用性,如: addAccountMember, addEmployeeMember,.. delAccount, delEmployee,.. getAccountMember, getEmployeeMember,.. getNextAccountID, getNextEmployeeID,..   对于同一种功能存在这么多不同名称的函数想起来就让我感到可怕,在我们的这个简单的例子中只对6个表实现了三种功能,我们需要为每个表实现4种不同名称的函数,结果,我们需要记住4*6=24个不同名称的函数及它们所对应的功能,如果,如果我们要对更多的表实现更多的功能..,真的不敢相象我们到底要实现多少个不同名称的函数。我想,不用等到函数接口数量爆炸,我的脑子就先爆炸了。如果能够对同一种功能的函数使用一组相同的名字如: addMember delMember getMember getNextMemberID   那么,我们的接口名称数量就只与实现的功能多少成常数关系,而与我们要操作的表的个数无关了,整个程序就应该清晰多了。共2页。 1 2 8 :   泛型程序设计(Generic Programming) 是建立在C 的Template机制基础上的一种完全不同于面向对象的程序设计思维模式,STL是泛型概念的一套实作产品。Loki是一个与Boost齐名的开放源码的C 程序库,它通过一些精巧的装置为常规C 开发提供了一些很有用的工具。STL非常好用,弹性非常大,效率也很理想。目前几种主流的C 编译器均有相关的STL实现,而个人认为目前非常流行的Visual c 6.0平台中开发文档应用程序时,其文档序列化的功能非常好用,但由于其序列化能力建立在MFC之上,并不被STL支持,所以,如何既拥有STL的效率及通用性,又保留MFC的序列化能力,便成了Visual C 6.0平台上运用STL技术开发文档应用程序时不得不面对的一个问题,在这里我就以非常流行的Visual C 6.0 SP5平台结合一个假定的例子来介绍一下如何在Visual C 6.0中结合使用STL、Loki及模板技术来开发一个文档应用的开发历程,希望能对大家有所启发。  示例  先来简单介绍一下我所用到的例子:一个简单的商务进销存基本应用(不必关注细节),它应该包含:职员(Employee)、产品(Product)、仓库(Storage)、往来单位(Supply)、帐户(Account)、单据(Bill)等等,由于每种信息均应有唯一标识,所以我在这里选用STL中的map来表示如下(为了说明简单起见,我们只列两种): std::map<size,Employee*> itsEmployees; //职员表std::map<size,Product*> itsProducts; //产品表..   第一步:实现  我们将以上map放入多(单)文档应用程序的文档类中,很显然,我们必须对每一个表至少提供以下三种最基本的操作:添加新成员函数、删除指定成员函数、获取指定成员函数。  对于添加新成员,我们可以实现如下: size addAccountMember(Account* e); //添加帐户{  //获取下一个可用的ID号 size id=getNextAccountID();  itsAccounts[id]=e;  return id; }size addEmployeeMember(Employee* e);//添加职员{  //获取下一个可用的ID号 size id=getNextEmployeeID();  itsEmployees[id]=e;  return id; } ..   接下来的删除方法仅有一个size(唯一标识)参数,实现如下: void delAccount(size ID); //删除指定帐户{ itsAccounts.erase(ID); }void delEmployee(size ID); //删除指定职员{ itsEmployees.erase(ID); }..  获取指定成员的方法如下: Account* getAccountMember(size ID) //获取指定帐户{ return itsAccounts[ID]; } Employee* getEmployeeMember(size ID) //获取指定职员{ return itsEmployees[ID]; } ..   另外,我们还要为每一个表提供一个获取下一个可用ID的成员函数: //获取下一个可用职员号Size getNextEmployeeID() {  if (itsEmployees.empty())   return 1;  std::map<size,Employee*>::iterator it=itsEmployees.end(); --it;  return it->first 1; }//获取下一个可用帐户号Size getNextAccountID() {  if (itsAccounts.empty())  return 1;  std::map<size,Account*>::iterator it=itsAccounts.end();  --it;  return it->first 1; }..  第二步:分析  以上实现的确达到了我们的设计目的,但仅从直观上来看我就觉得它应该还有改善的空间,最简单的原因:因为它的命名混乱,没有通用性,如: addAccountMember, addEmployeeMember,.. delAccount, delEmployee,.. getAccountMember, getEmployeeMember,.. getNextAccountID, getNextEmployeeID,..   对于同一种功能存在这么多不同名称的函数想起来就让我感到可怕,在我们的这个简单的例子中只对6个表实现了三种功能,我们需要为每个表实现4种不同名称的函数,结果,我们需要记住4*6=24个不同名称的函数及它们所对应的功能,如果,如果我们要对更多的表实现更多的功能..,真的不敢相象我们到底要实现多少个不同名称的函数。我想,不用等到函数接口数量爆炸,我的脑子就先爆炸了。如果能够对同一种功能的函数使用一组相同的名字如: addMember delMember getMember getNextMemberID   那么,我们的接口名称数量就只与实现的功能多少成常数关系,而与我们要操作的表的个数无关了,整个程序就应该清晰多了。共2页。 1 2 8 : 下载本文示例代码


Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践Visual C 泛型编程实践
阅读(86) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~