c++ lambda表达式(lambda 演算)
本文是工厂设计自考毕业论文及泛型、lambda表达式和std相关论文的样本。
罗红闵军
(宜宾大学图书馆,四川宜宾644000)
摘要:抽象工厂在软件设计中应用广泛,但传统的抽象工厂实现方法存在诸多不足。随着技术的发展,设计模式的实现方法也在不断改进。新的C 11标准发布后,出现了许多改进方案。基于这些改进,本文将使用C 11的lambda表达式、std:function函数模板等新技术。通过对数据结构和代码结构的优化,进一步改进了通用抽象工厂的设计,并给出了“新通用抽象工厂”的实现方法。实验结果表明,该方法更加简洁高效,具有更强的可重用性,很好地实现了对产品类型变化、参数变化和异构组合的支持。实现方法和代码是实用的,可用于软件项目。
关键词:c11λ。功能;仿制药;抽象工厂
中间图分类号:TP311.1
文件识别码:a
介绍
抽象工厂是最普遍、最抽象的工厂模式之一。由于这种模式的使用有利于实现高内聚、低耦合的设计目标,因此在软件设计中得到了广泛的应用。然而,传统的抽象工厂实现方法存在许多缺点,如实现复杂、类型复杂、类型依赖性强、可重用性差等。随着技术的发展,人们继续使用多态机制、模板编程、泛型编程等技术来改进设计模式[1]。新的C 11标准发布后,出现了许多改进方案,例如将特定的工厂构造器保存到关联容器中以实现自动注册,使用可变参数模板和类模板来实现通用工厂,使用嵌入式类来简化设计等。在这些改进的基础上,本文将利用C 11 lambda表达式和std:function函数类模板等新技术,通过优化数据结构和代码结构,进一步改进泛型抽象工厂的设计,并给出一个更加简洁高效的“新泛型抽象工厂”的实现。
2抽象工厂
抽象工厂属于创造模式。简而言之,抽象工厂是用来完成“多个系列的相互依赖的特定产品”的创作,避免了客户端程序和这个“多个系列的特定产品创作作品”[2之间的紧密耦合。抽象工厂的结构如图1所示。
通用抽象工厂的3 C 11实现
抽象工厂(由C 11)
泛型编程技术可以提高编程效率,实现非侵入式实现,并大大提高代码重用率[3]。在设计模式实现技术中,泛型编程技术是改进抽象工厂传统实现的有效手段。通过新的C 11标准通用编程技术,可以实现具有可变产品类型、可变参数和异构组合的通用抽象工厂。图2显示了C 11实现的可变参数通用抽象工厂的结构。这个实现包括两个类模板:通用工厂类通用工厂和嵌入式类特定工厂注册类注册[4]。
4使用lambda表达式和STD :3360函数类模板设计“新的通用抽象工厂用lambda表达式和STD :3360函数类模板”
尽管上述通用抽象工厂设计方法使用了诸如关联容器、可变参数模板和嵌入式类等技术,但仍有优化的空间。接下来,本文将在这些改进的基础上进一步优化,并引入一个更简洁高效的实现“新通用抽象工厂”。
4.1“新通用抽象工厂”结构图
“新通用抽象工厂”的结构如图3所示。
4.2用λ表达式替换嵌入类
Lambda表达式是C 11引入的最重要和最常用的特性之一。它具有简单高效、声明式编程风格和实现函数闭包的优点[4]。先前介绍的通用抽象工厂设计方法使用嵌入式类来生成特定产品的创建函数[5]。其结构图如图2所示。基于以前的设计,可以使用lambda表达式来代替嵌入式类。Lambda表达式直接用作特定产品的创建函数。它的结构图如图3所示,代码可以在下面完整的代码中看到。相比之下,lambda表达式用于替换嵌入式类,这显然简化了代码结构,但可读性可能会更低。
4.3使用std:function函数类模板来存储和操作lambda表达式
Lambda表达式是一个匿名函数对象(或模仿函数)。它的特定类型是依赖于特定实现的唯一函数对象类型。这种类型的名称只有编译器[6]知道。虽然一些简单的lambda表达式可以直接或间接转换为函数指针,但通常建议使用auto关键字来标识Lambda表达式的类型。如果你想得到特定类型的lambda表达式,你可以使用C 11提供的decltype操作符来得到它。如果用户想要将lambda表达式作为参数传递,他需要使用std:function函数对象来捕获。
Std :3360函数类模板是一个通用的多态函数封装工具。它是c语言中存在的各种可调用实体的类型安全封装(可调用实体如函数指针是类型不安全的)[7]。通过这种封装,形成了单个可调用的std :3360函数new对象,使得代码简单明了。
4.4使用std:function函数类模板来存储和操作特定的工厂信息
在“新通用抽象工厂”的设计中,关键数据成员m_mapConFactory用于存储特定产品标识和特定工厂创建函数指针的列表信息。使用lambda表达式而不是嵌入式类作为特定产品的创建函数,需要相应地更改m_mapConFactory存储的数据类型。
特定产品创建函数的函数指针最初存储在m_mapConFactory中(图2)。它现在不能直接保存为函数指针,但需要保存为由std:function函数类模板封装的lambda表达式。具体定义见图3和下面完整的代码。
5优化“新通用抽象工厂”的数据结构
新通用抽象工厂的数据结构)
为了优化“新通用抽象工厂”保存的数据结构,对关键数据成员m_mapConFactory的结构进行了调整。有关详细信息,请参考下面完整代码中m_mapConFactory的定义。通过这种调整和其他相应的修改,用户可以更容易地注册特定的工厂。可以通过指定特定产品的类型来完成注册(参见以下示例)。注册特定工厂时,“新通用抽象工厂”类将自动生成唯一的特定产品序列号,并根据用户提供的特定产品类型获取其类型名称,而无需用户从外部输入特定产品的类型标识。最后,数据将被本地构造为容器元素,并存储在m_mapConFactory容器中。
6“新通用抽象工厂”代码优化(代码
新通用抽象工厂优化)
“新通用抽象工厂”的代码设计也得到了优化。GenericFactory类的模板参数被简化为只包括两部分:抽象产品类和特定产品构造函数的变量参数列表0-n项。模板参数的分配方法比较合理,实质上是规定了具体产品构造函数的具体类别:包括返回值和参数列表。返回值必须是AbsProduct*指针类型、参数类型和数字列表参数.参数必须一致。当参数类型和特定产品构造函数的数量不同时,将生成不同版本的GenericFactory实例。
GenericFactory类通过静态函数和静态变量实现了一个简单的单例。所有构造函数都是私有的,不允许外部构造。外部只能通过调用其静态接口函数get_Instance来获取唯一的静态实例Singleton_GenericFactory。
特定的工厂注册功能寄存器只有一个模板参数:特定的产品类型ConProduct,它要求ConProduct类是AbsProduct的子类。在特定产品构造函数的返回值为AbsProduct*指针类型且参数列表一致的前提下,可以注册具有不同实现细节的特定工厂。
当函数参数是常量引用时,用户可以传入临时对象或创建的变量。因此,GenericFactory类的成员函数试图通过常量引用传入参数,以减少临时对象的构造和复制。此外,不需要修改数据成员的成员函数尽可能声明为常量类型,以提高代码的健壮性。
7“新通用抽象工厂”完整的实现代码(完整
新通用抽象实现代码
工厂)
本文介绍的“新通用抽象工厂”的完整实现代码如下。应该注意的是,本文中给出的代码是基于新的C 11标准实现的,并且只能在支持新的C 11标准的编译器中正常编译和使用,例如Visual Studio 2013和更高版本。
//GenericFactory.h,泛型抽象工厂头文件v2.0.3
#pragma一次
#包含函数
#包括记忆
#includestring
#includemap
//泛型工厂类泛型工厂包含2个模板参数:
//抽象产品类,具体产品类构造函数变量参数列表0-n项
模板类型名absproduct,类型名.args//absproduct是抽象产品的缩写。
泛型工厂类
{
private:
GenericFactory() {}
~GenericFactory() {}
通用工厂等于删除;
通用工厂等于删除;
GenericFactory运算符等于(const GenericFactory)等于delete
GenericFactory运算符等于(GenericFactory)等于delete
///std:map特定产品序列号,std:pair特定产品类型标识字符串,特定产品创建功能的功能指针
std:mapsize_t,std : pair STD : string,STD
:功能产品*(常量参数.)m _ mapConFactory
public:
内联静态GenericFactory*get_Instance()
{
静态GenericFactory Singleton _ GenericFactory;
返回Singleton _ GenericFactory
}
//寄存器只有一个模板参数:特定产品类ConProduct,它要求ConProduct类是AbsProduct的子类。
//在特定产品构造函数的返回值为AbsProduct*类型且参数列表一致的前提下,可以注册不同实现细节的特定工厂
template typename ConProducT//conp,ConProduct是concetproduct的缩写。
布尔寄存器()
{
//获取按顺序递增的产品的序列号,以替换成员变量m_nNo
Size_t nConp等于(0等于m_mapConFactory.size()?0:((-m _ MapConFactory . end())-first)1);
//获取特定的产品类型名称
Std :3360 stringstronp等于typeid(ConProduct)。name();
//获取特定产品创建函数的指针(λ表达式)
自动函数创建器等于[)(常量.参数){returnnewconproduct(参数.);};
//就地构造容器元素以减少临时对象副本。工厂简称为混凝土工厂
Autopaint ret等于m _ MapConFactory . posite(NConP,
make_pair(strConp,Funcreator));
返回pairRet.second
}
bool取消注册(常量大小_tnConp)
{
return m _ mapconfactory . erase(nconp)等于1;
}
//当函数参数是常量引用时,用户可以传入临时对象或创建的变量。
//因此,成员函数尽力通过常数引用传递参数,以减少临时对象的构造和复制。
bool取消注册(常量std:stringstrConp)
{
返回Unregister(GetNum(StRConp));
}
//没有修改数据成员的成员函数尽可能声明为常量类型
size_t getNum(常量std:stringstrConp)常量
{
用于(自动m:m_mapConFactory)
{
如果(strConp等于m.second.first)返回m.first
}
返回SIZE _ MAX//SIZE_MAX是32位的uint _ max和64位的_UI64_MAX,以适应大小类型
}
std:string getStr(常量大小_t nConp)
{
返回(m _ mapconfactory.find (nconp)等于m_mapConFactory.end())?
STD : string():m _ mapConFactory[nConp]。首先;
}
size_t getSize()常量
{
返回m _ MapConFactory . size();
}
AbsProduct*getConProduct(常量大小_t nConp,常量参数.args)
{
返回(m _ mapconfactory.find (nconp)等于m_mapConFactory.end())?
[核电厂]。第二(args.);
}
AbsProduct*getConProduct(常量std:string strConp,常量参数.args)
{
返回getConProduct(getNum(strConp),参数.);
}
STD : shared _ PtRabsProductGetConProduct _ shared _ ptr(常量大小_t nConp,常量参数.args)
{
返回STD : shared _ PTRabsProduct(GetConProduct(NConP,参数.);
}
STD : shared _ PtRabsProductGetConProduct _ shared _ ptr(常量std:string strConp,常量Args.args)
{
返回STD : shared _ PTRabsProduct(GetConProduct(GetNum(StRConp),参数.);
}
STD : unique _ PtRabsProductGetConProduct _ unique _ ptr(常量大小_t nConp,常量参数.args)
{
返回STD : unique _ PTRabsProduct(GetConProduct(NConP,参数.);
}
STD : unique _ PtRabsProductGetConProduct _ unique _ ptr(常量std:string strConp,常量Args.args)
{
返回STD : unique _ PTRabsProduct(GetConProduct(GetNum(StRConp),参数.);
}
};
8“新通用抽象工厂”的实际使用
新的通用抽象工厂)
8.1“新通用抽象工厂”的使用
“新通用抽象工厂”的设计合理全面,能够满足抽象工厂、简单工厂、可变参数、异构组合以及大量特定产品[8]的实施要求。它使用起来也非常简单。首先,通过通用工厂:3360 GET _ Instance调用其注册函数来创建各种特定的工厂。指向各种特定工厂的创建函数的指针存储在m_mapConFactory容器中。接下来,用户可以通过通用工厂:3360 GET _ Instance调用各种常见的接口函数,使得使用各种函数更加灵活方便。
用户可以调用getNum获取特定产品类型的序列号;调用getStr获取特定产品类型的标识字符串;调用getSize获取现有特定工厂的数量。创建和取消特定工厂的各种接口函数都设计了相应的重载函数。用户可以通过特定的产品序列号或特定的产品类型字符串来完成所需的工作。应该注意的是,getConProduct接口返回容器内部分配的堆内存指针,用户需要管理他们的生命周期。建议使用返回智能指针的getConProduct_shared_ptr或getConProduct_unique_ptr接口,这样用户就不必管理他们的生命周期。
如果用户的需求更复杂,抽象的工厂需求可以通过功能封装来实现,一系列相关产品可以封装在一个功能中,实现一次创建一系列相关产品的需求(见下面的例子8.3)。
8.2特定产品构造者的可变参数
如果已经定义了Shape基类以及Rect和Circle子类,则可以使用以下代码注册特定的工厂并创建特定的产品。Rect和Circle子类的构造函数参数是可变的,参数的数量和类型可以不同。子类Rect的构造函数有三个无符号参数cpoint和cpoint,子类Circle的构造函数有两个参数cpoint和双[9]。例如,以下代码用于完成注册特定工厂、创建特定产品对象和调用其Draw函数的工作:
//注册并创建Rect类对象,并调用其Draw函数。首先获取泛型工厂类指针
//类型参数为:抽象产品类,具体产品类构造函数的变量参数列表中的0-n项
Auto pGF0等于generacifactoryshape,无符号,c point :3360 get _ instance();
PGF 0-RegisterRect();
//注册特定的工厂
//创建一个特定的产品并调用它的绘图函数
PgF 0-GetConProduct _ shared _ ptr(0,0,连接点(3,4),连接点(5,6))-Draw();
//注册并创建一个圆类对象,并调用它的Draw函数
Auto pGF1等于genericforyshape,cpointe,double :3360 get _ instance();
PGF 1-RegisterCircle();
//注册特定的工厂
//创建一个特定的产品并调用它的绘图函数
PgF1-GetConProduct _ shared _ ptr(0,CPoint(7,9),3.3)-Draw();
这个例子的结构如图4所示。
8.3特定植物的异质组合
在抽象工厂的应用中,经常会提到一个典型的例子。跨国公司在计算不同国家员工的工资时可能会使用不同的组合。假设美国雇员的工资包括奖金、补贴、税收和其他三部分。中国员工的工资包括奖金、补贴、税收和住房公积金。使用本文改进的“新通用抽象工厂”,通过函数[9封装不同抽象工厂的需求,可以更好地实现这种异构组合。例如,以下代码用于完成注册特定工厂、创建特定产品对象和调用特殊业务逻辑的工作:
//注册一个特定的工厂,调用特殊的业务逻辑:中国工厂
void GetChineseSalary(双数据库薪资)
{
//为了简化过程,为通用抽象工厂实例定义指针变量
Auto pGF等于generic factorybasecial :3360 get _ instance();
//注册特定的工厂
pGF-RegisterHineSebronus();
PgF-RegisterHinesSubIdy();
pGF-RegisterHineSetax();
pGF-RegisterChineseFound();
//住房公积金
//调用特殊业务逻辑
双点几乎等于
pGF-GetConProduct _ unique _ ptr(0)-
获取数据(数据库薪资)
pGF-GetConProduct _ unique _ ptr(1)-
GetData(数据库薪资)-
pGF-GetConProduct _ unique _ ptr(2)-
GetData(数据库薪资)-
pGF-GetConProduct _ unique _ ptr(3)-
获取数据(数据库工资);//住房公积金
//输出信息
中国工厂:端;
cout ' dBasicSalayendl等于dBasicSalaryendl
Cout'dActualSalary等于dBasicSalary dOtherSalaryendl
}
这个例子的结构如图5所示。
结论
总而言之,抽象工厂的实施一直在不断改进。新的C 11标准发布后,出现了许多改进方案。在这些改进的基础上,本文通过优化数据结构和代码结构,使用新的技术如C 11的lambda表达式、std:function函数类模板等,进一步改进了通用抽象工厂设计。给出了“新通用抽象工厂”的一个更简洁有效的实现。实验结果表明,该方法更加简洁高效,具有更强的可重用性,并优雅地实现了对产品类型、参数和异构组合的支持。实现方法和代码是实用的,可用于软件项目。
参考
[1]贝马迪毫升,西米蒂勒米,卢卡广东。使用DSL驱动的图形匹配方法的设计模式检测,[·J .软件进化过程杂志,2014,26(12):1233-1266。
一种基于特征类型的可定制模式识别设计方法[[]。阿拉伯科学工程杂志,2014,39(12):8851-8873。
[3]斯蒂芬·普拉塔。《初级读本》,第六版,[出版社,2011年版。
齐雨。《C 11:代码优化的深度应用和工程应用》,[M .北京:机械工业出版社,2015。
闵军,罗红。C 11实现可变参数通用抽象工厂[。软件工程,2017,20 (05) :18-22。
[6]王敏德(加拿大),IBM XL编译器中国开发团队,作者。深入了解C 11:C 11 [M的新特性分析和应用。北京:机械工业出版社,2013。
[7]马克·格雷戈瓦(美国),作家。张永强,跨州。高级编程(第三版)[男]。北京:清华大学出版社,2015:519-521。
[8]B·伽马·埃里希(美国),等人,李英俊等人,译。设计模式:可重用面向对象软件基金会[。北京:机械工业出版社,2000。
[9]约书亚·克里耶夫斯基(美国)。杨光,刘继承,横贯。重建和模型(修订)[男]。北京:人民邮电出版社,201:51-59。
作者简介:
闵军(1966-),男,硕士,研究员。研究领域:C语言编程、设计模式、计算机网络。
罗红(1970-),女,专业,工程师。研究领域:数据分析与处理、电路设计、信息管理系统。
工厂设计文件的参考材料:
食品工厂设计论文
毕业设计杂志
毕业设计
设计提交
机械设计与制造杂志
毕业设计规范
本文的结论是,本文是一篇关于工厂设计硕士学位和本科学位的泛型和lambda表达式和std论文模型论文的专题研究的模型论文、文献综述和论文标题的参考资料。