当前位置:大学毕业论文> 专科论文>材料浏览

序列论文写作技巧范文 和基于闭包封装和序列展开实现可选用参泛型抽象工厂有关硕士论文范文

主题:序列论文写作 时间:2024-04-20

基于闭包封装和序列展开实现可选用参泛型抽象工厂,本文是关于序列相关学术论文怎么写与闭包和泛型和封装有关硕士论文范文.

序列论文参考文献:

序列论文参考文献 食品工厂设计论文连续型电子期刊连续型电子期刊可以评职称吗

  摘 要:C++11、C++14、C++17等新标准发布后,涌现出许多泛型抽象工厂的设计方案.不过,一般泛型抽象工厂的设计,都要求入参列表与用参列表必须一致.本文将在以往设计的基础之上,基于闭包封装和序列展开、使用C++1x的std::integer_sequence、lambda表达式、tuple等新技术,通过数据结构和代码设计的优化,给出一种“可选用参泛型抽象工厂”的实现方式.测试结果显示,该方式复用性更好、更为精简高效,优雅地实现了对产品类型可变、异类组合、参数可变、可选用参等需求的支持.该实现方式及代码具有较强实用价值,可以实际应用到软件项目中.

  关键词:闭包封装;序列展开;integer_sequence;可选用参;泛型抽象工厂

  中图分类号:TP311.1

文献标识码:A

  1 引言(Introduction)

  抽象工厂模式主要是用于完成“多系列相互依赖的具体产品”的创建工作,避免客户程序和这种“多系列具体产品创建工作”的紧密耦合[1].随着技术的发展和进步,人们先是使用多态机制和模板编程改进设计模式,随后采用的泛型编程技术是改进抽象工厂传统实现方式的一种有效手段[2].C++11、C++14、C++17等新标准发布后,涌现出许多泛型抽象工厂的改进方案,比如将具体工厂构造函数存放到STL关联容器中实现自动注册、使用类模板和可变参数模板实现泛型工厂、使用lambda表达式和std::function类模板简化设计等.然而,一般泛型抽象工厂的设计,都要求入参列表与用参列表必须一致,本文将在以往改进的基础之上,基于闭包封装和序列展开、使用C++1x的std::integer_sequence、lambda表达式、tuple等新技术[3],通过数据结构和代码结构的优化,给出一种“可选用参泛型抽象工厂”的实现方式.

  2 基于闭包封装和序列展开实现“可选用参泛型

   抽象工厂”(Implementation of Generic Abstract Factory of Optional Reference Parameter based on closures encapsulation and sequence expansion)以往泛型抽象工厂的设计,虽然使用了关联容器、可变参数模板等新技术进行优化[4],但是它们都要求入参列表与用参列表必须一致.下面,本文将在以往设计的基础上进一步改进,介绍“可选用参泛型抽象工厂”的实现方式.

  2.1 “可选用参泛型抽象工厂”的结构图

  下面给出的图1便是“可选用参泛型抽象工厂”的结构图.

  2.2 可选用参是指:“用参列表”可以任意选用“入参列表”中的参数

  本文介绍的可选用参涉及两个概念,“入参列表”和“用参列表”.二者的关系可以通俗地比喻为餐馆菜单(入参列表)和用户点菜(用参列表)之间的关系.

  这里的“入参列表”就是具体产品创建函数CreateConp的参数表(参见2.3),它是在实例化泛型抽象工厂时确定的,定义后就不能改变.对每一个泛型抽象工厂实例来说入参列表都是固定不变的,它规定了用户在创建具体产品时必须输入的参数列表,所以简称为入参列表.入参列表类似于餐馆提供的供应菜单(在实际使用中,入参列表可以使用函数封装、通过函数缺省参数方式进行简化).

  这里的“用参列表”就是具体产品构造函数ConProduct的参数表(参见2.3),它是在已经定义的泛型抽象工厂实例中注册具体工厂时确定的,它规定了构造具体产品对象时实际使用的参数列表,因而简称为用参列表,这就类似于顾客点菜清单.

  以往泛型抽象工厂的设计,都要求这两个参数列表必须一致,本文所说的可选用参,就是希望在注册和使用具体工厂创建具体产品实例时,“用参列表”可以任意选用“入参列表”中的参数,既可以连续选用、也可以散列选用、也可以不选.这就类似于,顾客到餐馆用餐时可以任意点菜,即可以任意点选餐馆供应菜单(入参列表)中的菜品享用,顾客点选的菜单就是(用参列表).当然,用参列表必须小于等于入参列表,也就是说顾客点菜菜单不能超出餐馆供应菜单的范围.

  2.3 具体产品创建函数和具体产品构造函数的不同

  在“可选用参泛型抽象工厂”的设计中,请注意区分具体产品创建函数CreateConp(以“入参列表”为参数表,类似餐馆菜单)和具体产品构造函数ConProduct(以“用参列表”为参数表,类似用户点菜)的不同.简单地说,具体产品的创建函数CreateConp包含和封装了具体产品的构造函数ConProduct.数据成员m_mapConFactory里直接存放的是包含lambda表达式funConp的std::function指针;funConp中含有CreateConp;CreateConp通过CreateConp_helper又包含ConProduct,可以参见后面的完整代码.它们之间的包含关系是:

  m_mapConFactorystd::function<funConp>CreateConpCreateConp_helperConProduct.

  对每一个泛型抽象工厂实例来说,具体产品创建函数CreateConp的类型都是唯一的,其返回值是抽象产品类指针、其参数表就是上面介绍的“入参列表”,入参列表是在实例化泛型抽象工厂时确定的.在同一种泛型抽象工厂实例中,可以注册不同用参列表的具体工厂,每一种具体工厂对应一种具体产品类型定义的构造函数ConProduct,具体产品构造函数的返回值必须是抽象产品类指针、其参数表就是上面介绍的“用参列表”,用参列表可以任意选择入参列表中的参数.

  2.4 数据结构和代码优化

  在泛型抽象工厂设计中,一般都设置了一个关键数据成员m_mapConFactory,其中存放着具体产品标识与具体产品创建函数之间的对应信息.在本文提供的实现方式中,以lambda表达式作为具体产品的创建函数,关键数据成员m_mapConFactory中要保存的便是以std::function类模板封装的lambda表达式[5].“可选用参泛型抽象工厂”的代码设计也进行了相应优化,可参见后面的完整代码.

  3 通过闭包封装实现类型擦除(To erase type based on the closures encapsulation)

  要实现“可选用参泛型抽象工厂”,需要将不同类型具体产品创建函数的数据保存到同一个STL容器之中,我们可以借助类型擦除技术来实现[6].本文将使用闭包封装技术来实现类型擦除.

  简单地说,闭包(closure)就是带状态的函数.闭包封装就是借助闭包来擦除类型,实质上是把一些类型信息保存到闭包之中隐藏起来,从而实现类型擦除的目的.C++11的lambda表达式就是一种闭包类型,可以把具体类型作为lambda表达式的参数隐藏起来,再用std::function类模板封装lambda表达式,就可以通过lambda表达式来实现闭包封装[7].由于闭包本身的类型是确定的,因此可以把它存放到普通STL容器中,需要时再从闭包中取出其具体类型.

  本文介绍的“可选用参泛型抽象工厂”的实现方式,就是通过lambda表达式来实现闭包封装,达到类型擦除的目的.具体实现可参见后面完整代码中的m_mapConFactory容器、Register_helper函数等相关内容.

  4 通过序列展开实现可选用参(To implement optional reference parameter based on the sequence expansion)

  4.1 利用C++14的std::integer_sequence展开tuple作为函数参数

  “可选用参”是“可选用参泛型抽象工厂”的关键特性,我们可以利用C++14的std::integer_sequence展开tuple作为函数参数的方式来具体实现.C++11中新增的std::tuple元组类模板是std::pair的通用扩展,C++14中新增的std::integer_sequence整型序列类模板用于实现编译期整数序列.有了这两样工具,我们便可以借助C++11的可变参数模板和std::integer_sequence的模板参数自动推导机制,实现展开tuple作为函数参数的功能[8].具体可参见后面完整代码中的Register_helper、CreateConp和CreateConp_helper等函数.

  4.2 获取tuple中指定序列作为函数参数

  上面我们已经实现了使用C++14的std::integer_sequence展开tuple作为函数参数的功能.但是,这种方式还只能简单地将tuple中的所有元素展开作为函数参数.我们要实现泛型抽象工厂的“可选用参”,就需要实现获取tuple中指定序列的元素组作为函数参数的功能.

  为此,一般的整数序列就不能满足要求了,我们需要获取指定起点和终点的整数序列.通过对std::integer_sequence的简单变换,就可以很优雅地生成Begin到End-1的升序序列,具体实现可参见后面完整代码中的make_index_range和IndexAdd函数.有了make_index_range这一利器,我们便可以轻松实现获取tuple中指定序列的元素作为函数参数的功能.另外,要实现指定tuple中任意散列的元素作为函数参数的功能,可以直接使用可变参数模板std::index_sequence<UseHash...>进行指定即可.借助以上两种方式,便可以设计出“可选用参泛型抽象工厂”.具体实现可参见后面完整代码中的Register、RegisterHash、CreateConp和CreateConp_helper等相关函数.

  4.3 本文提供两种任意选择用参序列的方式

  为了方便注册,本文介绍的“可选用参泛型抽象工厂”设计了两种具体工厂注册函数Register和RegisterHash,用户可以通过两种方式任意指定用参序列,不过,使用时都需要注意不能越界.具体实现可参见后面完整代码中的Register、RegisterHash.

  5 “可选用参泛型抽象工厂”的完整实现代码 (Complete implementation code of "GenericAbstract Factory of Optional Reference Parameter")

  以下是本文介绍的“可选用参泛型抽象工厂”的完整实现代码.用户需要注意的是,下面提供的代码是基于C++14新标准实现的,需要在支持C++14的编译器中才能正常编译,比如Visual Studio 2015[9]、CodeBlocks 16.01 with GCC 6.1及以上版本[10].

  6 “可选用参泛型抽象工厂”的实际使用(Actual use of Generic Abstract Factory of Optional Reference Parameter)

  6.1 具体产品构造函数的参数可以任意选择

  该例中定义了MyShape基类,以及三个子类MyRect、MyLine、MyCircle,借助本文设计的“可选用参泛型抽象工厂”,便可以优雅地实现众多具体工厂的注册和具体产品的创建.MyRect、MyLine两个子类的构造函数都包含三个参数、但顺序不同,MyCircle子类与前两个子类的构造函数参数个数、类型都不相同,其结构图见图2.

  如果使用一般泛型抽象工厂设计,每种不同参数的具体工厂都需要单独注册一个泛型抽象工厂实例,代码繁琐低效[11].使用本文介绍的“可选用参泛型抽象工厂”,在入参列表一致的情况下,可以将不同用参列表的具体工厂都注册到一个泛型抽象工厂实例之中,然后简单地使用循环方式便可以实现用户业务功能的调用,代码得以大大简化,注册的具体工厂越多,简化得就越为显著.示例代码如下[11]:

  //在入参一致的情况下,可将不同用参的具体工厂都注册到一个泛型抽象工厂实例之中

  //模板参数是:抽象产品类、入参列表

  6.2 具体工厂的异类组合

  讨论抽象工厂时,有一个经常用到的案例,不同电脑厂商生产各种电脑部件的例子.假设Dell电脑需要自己生产机箱、主板、内存、显卡等四种部件,联想电脑需要自己生产机箱、主板、内存、显卡、键盘、鼠标等六种部件.借助本文改进的“可选用参泛型抽象工厂”,使用函数封装不同抽象工厂的需求,便能够更为优雅地实现该例中的异类组合[5].

  7 结论(Conclusion)

  综上所述,抽象工厂模式的实现方式一直都在不断改进和完善.C++11、C++14、C++17等新标准发布之后,涌现出许多泛型抽象工厂的改进方案.然而,一般泛型抽象工厂的设计,都要求入参列表与用参列表必须一致.本文在以往设计的基础之上,基于闭包封装和序列展开、使用C++1x的std::integer_sequence、lambda表达式、tuple等新技术,通过数据结构和代码设计的优化,给出一种“可选用参泛型抽象工厂”的实现方式.测试结果显示,该方式复用性更好、更为精简高效,优雅地实现了对产品类型可变、异类组合、参数可变、可选用参等需求的支持.该实现方式及代码具有较强实用价值,可以实际应用到软件项目中.

  参考文献(References)

  [1] Design Patterns:Elements of Reusable Object-Oriented Software[M].USA:Addison-Wesley Professional,1994:99.

  [2] Bjarne Stroustrup.The C++ Programming Language Fourth Edition[M].USA:Addison-Wesley Professional,2013:699.

  [3] std::integer_sequence[EB/OL].http://en.cppreference.com/w/cpp/utility/integer_sequence,2018-07-06.

  [4] Variadic arguments[EB/OL].http://en.cppreference.com/w/cpp/language/variadic_arguments,2018-02-22.

  [5] 闵军,罗泓.用lambda表达式和std::function类模板改进泛型抽象工厂设计[J].软件工程,2017,24(09):9-14.

  [6] 祁宇.深入应用C++11:代码优化与工程级应用[M].北京:机械工业出版社,2015:267.

  [7] Stephen Prata.C++ Primer Plus,Sixth Edition[M].USA:Addison-Wesley Professional,2011:1184-1196.

  [8] Invoke the Callable object f with a tuple of arguments [EB/OL].https://doc.bccnsoft.com/docs/cppreference2015/en/cpp/experimental/apply.html,2018-07-02.

  [9] Support For C++11/14/17 Features(Modern C++) [EB/OL].https://msdn.microsoft.com/en-us//library/hh567368.aspx,2018-07-02.

  [10] C++ Standards Support in GCC [EB/OL].https://gcc.gnu.org/projects/cxx-status.html,2018-08-13.

  [11] 闵军,罗泓.C++11实现可变参数泛型抽象工厂[J].软件工程,2017,20(05):18-22.

  作者简介:

  闵 军(1966-),男,硕士,研究员.研究领域:C++程序设计,设计模式,计算机网络.

  覃凤清(1976-),女,博士,研究员.研究领域:图像处理与信息系统,多媒体通信.

概括总结:上文是一篇关于闭包和泛型和封装方面的序列论文题目、论文提纲、序列论文开题报告、文献综述、参考文献的相关大学硕士和本科毕业论文.

雪夜闭门拣落花
●李金荣家是什么年少的时候,以为一座房子或一个庭院,就代表一个家 后来才意识到,如果在那儿,你感觉不到身心愉悦,也唤不起你的留恋,那就不是家,是家的外壳,是你存在世间的一种空间符号,或是生存的落脚点 .

张扬和浮华风气的退潮:日本女人的名牌包
LV 包曾是街头一道亮丽的时尚风景以前有一个报道,说九成的日本女性都有路易·威登品牌的包,也就是LV 的包,但是你现在在的街头去兜一圈会发现,日本女性已经较少拎LV 的包了 在我们聊日本.

闭上眼睛,才会看到明亮的内心
人做梦,是在睡着的时候、闭着眼睛的时候 这说明,梦境,是在人闭着眼睛的时候看到的 由此看来,人有两双眼睛,一双眼睛长在脸上,长在脸上的眼睛,让我们看到了外面的这个世界 那另一双眼睛呢另一双眼睛又长在哪.

我买了两百块钱的包,很丢人吗
前几天在微信里发了张自拍,包不小心入镜了 有个读者在下面留言铃铛你这包好看耶,啥牌子的我说,淘宝买的,两百 要链接吗我发给你 她发了个尴尬的表情,说不用啦,两百块钱的包你也敢背啊我马上点进去看她的主页.

论文大全