




已阅读5页,还剩66页未读, 继续免费阅读
(计算机科学与技术专业论文)分布式高精度浮点运算服务器的设计与实现.pdf.pdf 免费下载
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
分类号 u d c 密缉 学校代码 1 0 4 9 7 _ _ _ 一 题目 金查奎高益廛澄:量鎏笠丛釜墨鲍选盐鱼塞盟 英 文d e s i g n a n di m p l e m e n t a t i o no fd i s t r i b u t e d 题 目一一h i g 鱼:p 墅曼q i 墨i q 壁e ! q 堑i 塾g :p q i 塾! 垒! q 监! 堑i q 照s 型茎垄 研究生姓名猩盟 姓名塞坐盗职称割塾撞学位盛 指导教师 单位名称盛垫墨墨盘堂 邮编4 3 0 0 7 0 申请学位级别亟一学科专业名称 盐簋垫銎堂鱼垫盔 论文提交日期2 q ! ! 生垒月一论文答辩日期2 q ! ! 生月 学位授予单位盛婆堡墨盘鲎学位授予日期 答辩委员会主席玺堡评阅人 壁垒丛 复;工霞 2 011 年4 月 洋文大论 2 墨位理位引学 独创性声明 j ! i i i i l llp l p irr l l l ll lrfll y 18 7 9 9 6 2 本人声明,所呈交的论文是本人在导师指导下进行的研究工作 及取得的研究成果。尽我所知,除了文中特别加以标注和致谢的地 方外,论文中不包含其他人已经发表或撰写过的研究成果,也不包 含为获得武汉理工大学或其他教育机构的学位或证书而使用过的材 料。与我一同工作的同志对本研究所做的任何贡献均已在论文中作 了明确的说明并表示了谢意。 签名:铅丝 日期:筮! ! 学位论文使用授权书 本人完全了解武汉理工大学有关保留、使用学位论文的规定, 即学校有权保留并向国家有关部门或机构送交论文的复印件和电子 版,允许论文被查阅和借阅。本人授权武汉理工大学可以将本学位 论文的全部内容编入有关数据库进行检索,可以采用影印、缩印或 其他复制手段保存或汇编本学位论文。同时授权经武汉理工大学认 可的国家有关机构或论文数据库使用或收录本学位论文,并向社会 公众提供信息服务。 ( 保密的论文在解密后应遵守此规定) 研究生( 签名) :毳呈逸导师( 签名) :拿竺建日期: 摘要 随着互联网技术的发展和网络环境的改善,w e b 应用程序获得了飞速的发 展,越来越多的传统本地程序纷纷推出w e b 版。有着广泛应用的高精度浮点运 算可以移植成为w e b 应用程序,开发出基于网络的高精度浮点运算服务器有着 重要的意义。 本文以高性能网络i o 框架的设计为切入点,实现了跨平台的高性能i o 设计模式;结合高精度浮点运算,完成了分布式的高精度浮点运算服务器,能 够通过添加服务器数量来获得服务器端的吞吐量的提升。本文的主要完成的工 作如下: 1 ) 将仿函数应用在面向对象程序设计中。仿函数可以代替函数指针;利用仿 函数可以降低面向对象程序设计的复杂度;仿函数能够简化一些设计模式 的实现。 2 _ ) 设计与实现了跨平台的线程库和网络库。使用预编译宏技术,将不同平台 下的网络a p i 和线程a p i 统一到相同的类型和接口内;利用仿函数实现了 简单易用的线程池模型。 3 ) 实现了跨平台的高性能网络i o 模型。e p o l l 是非阻塞同步的网络i o 模型, i o c p 是非阻塞异步的网络i o 模型,它们的工作原理、工作流程和工作平 台截然不同,本文通过修改它们的工作流程,将它们统- n “模拟”的异 步i o 模型内。 4 ) 对服务器端进行了分布式的拓扑结构设计。通常来说,影响服务器端性能 的原因一般是i o 和c p u 运算瓶颈,可以将网络i o 和c p u 运算划分到不 同的进程内,来突破性能瓶颈。本文通过设计网关服务器进程来承担i o , 通过设计浮点运算服务器进程来承担c p u 运算,其中网关服务器运行网关 进程,运算服务器则运行浮点运算进程,网关进程和浮点运算进程之间使 用s o c k e t 进行通信,来达到天然的分布式架构。每个网关服务器能够管理 和维护多个浮点运算服务器,客户端只需要连接到网关服务器就可以获得 服务,运算服务器只能够连接并注册到惟一的网关服务器。 此外,本文还设计应用层的通讯协议,确定了客户端和网关之间的通讯流 程,确定了服务器组内部服务器之间的通讯流程。 最后,本文在整合了软件硬件系统的基础上,对服务器端进行测试,测试 结果证明服务器端的设计是正确的、有效的,能够运用在高精度浮点运算的网 络服务器端。 关键词:高精度浮点运算,仿函数,跨平台,分布式 a b s t r a c t w i t ht h ed e v e l o p m e n to fi n t e r n e tt e c h n o l o g ya n di m p r o v e m e n to fn e t w o r k e n v i r o n m e n t , w e ba p p l i c a t i o n sh a v eh a dr a p i dd e v e l o p m e n t , a n dm o r ea n dm o r e t r a d i t i o n a ll o c a la p p l i c a t i o n sh a v er e l e a s e dt h e i rw e bv e r s i o n s t h eh i g hp r e c i s i o n f l o a t i n gp o i n tc a l c u l a t i o nc a na l s ob et r a n s p l a n t e dt ow e ba p p l i c a t i o n d e v e l o p i n g l l i g hp r e c i s i o nf l o a t i n g - p o i n tc a l c u l a t i o ns e l v e ra p p l i c a t i o nb a s e do nn e t w o r ks e r v e r i sv e r yu s e f u la n ds i g n i f i c a n t b a s e do nt h ed e s i g no fh i g hp e r f o r m a n c en e t w o r ki of r a m e w o r k ,t h i sp a p e r r e a l i z e dt h ec r o s s - p l a t f o r mh i g h - p e r f o r m a n c ef od e s i g np a t t e r n ,a n dt h ed i s t r i b u t e d h i g h - p r e c i s i o nf l o a t i n g - p o i n t c a l c u l a t i o n ss e f v e rc o u l do b t a i nt h ea s c e n s i o no f t h r o u g h p u tb ya d d i n gs e r v e ra m o u n t s t h em a i nw o r k sf i n i s h e di nt h i sp a p e rw e r ea s f o l l o w s : ( 1 ) m a k ef u l lu s eo ff u n c t o r si no b j e c t - o r i e n t e dp r o g r a m m i n g u s i n gf u n c t o r si n p l a c eo ff u n c t i o np o i n t e r sc a nr e d u c ep r o g r a m m i n gc o m p l e x i t y , a n ds i m p l i f yt h e r e a l i z a t i o no fd e s i g np a t t e r n ( 2 ) d e s i g na n dr e a l i z et h eg r o s s - p l a t f o r mm u l t i t h r e a da n d n e t w o r kl i b r a r y t h ea p i i n t e r f a c e so fn e t w o r ka n dt h r e a dw e r eu n i f i e dw i t hp r e - c o m p i l e dm a c r ot e c h n o l o g y b e t w e e nw i n d o w so p e r a t i n gs y s t e ma n dl i n u xo p e r a t i n gs y s t e m ;f h n c t o r sw e r eu s e d t or e a l i z et h ee a s y - t o - u s et h r e a dp o o lm o d e l ( 3 ) i m p l e m e n tt h eg r o s s - p l a t f o r mn e t w o r k i 0p a t t e r nw i t hh i g hp e r f o r m a n c e e p o l l , n o n b l o c k i n gs y n c h r o n o u sn e t w o r ki 0p a t t e r nu n d e rw i n d o w sp l a t f o r m ,i sq u i t e d i f f e r e n tw i t hi o c p , n o n - b l o c k i n ga s y n c h r o n o u sn e t w o r ki op a t t e r nu n d e rl i n u x p l a t f o r m , i no p e r a t i o np r i n c i p l e s a n df l o wp r o c e s s t h r o u g hm o d i f y i n gt h e i r w o r k f l o w s ,t h e y w e r eu n i f i e di n t ot h e s i m u l a t i o n a s y n c h r o n o n si op a t t e r n ( 4 ) c a r r yo n a d i s t r i b u t et o p o l o g ys t r u c t u r ed e s i g nf o rt h es e r v e rs i d e i ng e n e r a l ,t h e r e a s o n sl e dt ot h ep e r f o r m a n c eb o t t l e n e c k0 1 1t h es e r v e rs i d ea r ea l w a y sf r o mi 0a n d n c p u o p e r a t i o n d i v i d i n gn e t w o r kf o a n dc p uo p e r a t i o ni n t os t a n d a l o n ep r o c e s s e s c a na c h i e v el o a db a l a n c i n g t w ok i n d so fs e l v a p r o c e s s e sw e r ed e s i g n e d ,o n ei s g a t e w a yp r o c e s sr u n n i n g 0 1 1t h eg a t e w a ys e mf o rp r o c e s s i n gi 0 ,a n dt h eo t h e ri s t h ef l o a t i n g - p o i n tc a l c u l a t i o np r o c e s sn m n i n go nt h ef l o a t i n g - p o i n tc a l c u l a t i o n s e l - v e rf o rc p uo p e r a t i o n t h e s et w op r o c e s s e su s e ds o c k e tf o rc o m m u n i c a t i o nt o a c q u i r en a t u r a ld i s t r i b u t i o ns t r u c t u r e e a c hg a t e w a ys e r v e rc a nm a n a g ea n dm a i n t a i n s e v e r a lf l o a t i n g - p o i n ta r i t h m e t i cs a v e l s ,t h ec l i e n tj u s tn e e dl i n kt ot h eg a t e w a y s e r v e rt oa c q u i r es e r v i c ea n df l o a t i n g - p o i n tc a l c u l a t i o ns e r v e rc a no n l yl i n ka n d r e g i s tt oas o l eg a t e w a ys e r v e r i na d d i t i o n ,t h ea p p l i c a t i o nl a y e rp r o t o c o lw a sd e s i g n e d ,w h i c hd e t e r m i n e dt h e c o m m u n i c a t i o nf l o wa m o n g c l i e n t s ,g a t e w a ya n df l o a t i n g - p o i n tc a l c u l a t i o ns e r v e r s f i n a l l y , t h e s e r v e r c o m p l e t e dw a st e s t e d a f t e r i n t e g r a t i n gs o r w a r ea n d h a r d w a r es y s t e m ,a n dt h et e s tr e s u l t sp r o v e dt h ev a l i d i t ya n de f f e c t i v e n e s so ft h e a r c h i t e c t u r ea b o u td i s t r i b u t e d h i g h p r e c i s i o nf l o a t i n g - p o i n t c a l c u l a t i o ns e r v e r d e s i g n e d k e yw o r d s :h i g h - p r e c i s i o nf l o a t i n g - p o i n tc a l c u l a t i o n , f u n c t o r s ,c r o s s - p l a t f o r m , d i s t r i b u t e d m 目录 摘要l a b s t r a c t i i 第l 章绪论1 1 1 论文研究的背景和意义1 1 2 课题主要的研究内容3 1 3 作者的工作和论文结构。3 第2 章预备知识4 2 1 仿函数4 2 1 1 采用仿函数的原因4 2 1 2 仿函数的特点。5 2 2 基于仿函数的面向接口编程1 l 2 3c 1 0 k 问题以及不同平台下的解决办法。1 4 2 3 1 几种i o 模式的分析1 4 2 3 2 一个典型的c 1 0 k 问题1 7 2 3 3 使用e p o l l 解决c 1 0 k 问题1 9 2 3 4 使用i o c p 解决c 1 0 k 问题。2 0 第3 章分布式浮点运算服务器设计2 l 3 1 超高精度浮点运算2 1 3 1 1 高精度浮点运算的封装2 l 3 1 2 超高精度浮点运算解析器的设计2 l 3 2 浮点运算和分布式服务器端设计2 5 3 2 1 服务器端的功能划分2 5 3 2 2 浮点运算对服务器端影响2 7 3 2 3 分布式服务拓扑结构设计2 7 第4 章网络层的详细设计与实现3 0 4 1 确定跨平台开发3 0 4 2 跨平台网络程序库的设计和实现。3 1 4 3 跨平台线程库的设计和实现3 3 4 3 1 多线程相关接口和类型的统一3 4 4 3 2 基于仿函数的线程和线程池的设计3 5 4 4 高性能网络i o 设计模式的确定和实现4 0 4 4 1p o r t a b l ep r o a c t o r 模式4 1 4 4 2w i n d o w s 平台下的实现4 5 4 4 3l i n u x 平台下的实现4 7 第5 章总体实现和测试5 l 5 1 服务器之间的通信流程5 1 5 2 通信协议的定义5 4 5 3 测试结果5 5 第6 章总结与展望5 7 6 1 论文总结5 7 6 2 进一步展望5 8 参考文献5 9 墅贮谢6 2 攻读学位期间的主要研究成果6 3 武汉理工大学硕士学位论文 第1 章绪论, 1 1 论文研究的背景和意义 应用科学领域的大型科学计算需求始终是计算机的发展的主要驱动力。应 用科学领域对大型科学计算的需求几乎是无止境的,气候与生态环境、航空航 天、材料科学、武器物理等领域均需要千万亿次的科学计算。在这些领域中, 浮点运算占了很大的比例。 目前大部分的计算机系统内置的浮点数类型通常有两种,分别为3 2 位的单 精度和6 4 位的双精度,有些专用的计算机系统可能会提供更大的浮点数,例如 英特尔公司的浮点运算单元i n t e l 8 0 8 7 协处理器就能够提供8 0 位长的浮点数, 来存储浮点运算的中间结果。当然,也有一些系统或者语言能够提供超高精度 的浮点数,比如p y t h o n 语言就能够提供超高精度的浮点运算,但是这些运算一 般都是通过软件方式模拟实现的。 无论是硬件实现的浮点数,还是软件模拟出来的浮点数都遵循电气电子工 程师协会( i e e e ) 所制定的i e e e7 5 4 标斛1 1 。 i e e e 7 5 4 标准使用三元组 s ,e ,m 表示一个浮点数n ,其中s 表示浮点数n 的符号位,e 表示浮点数n 的偏移指数位,m 表示浮点数n 的尾数位。如图 1 1 所示: 黜最高位 图1 - 1 浮点数的三元组表示 n 的实际值n 由下列式子表示: n = ( 1 ) 5 xm 2 e 对于内置的浮点数类型,有效位数很有限,例如单精度浮点数,它的尾数 为2 3 位,偏移指数为8 位,符号位为l 位,这些字段存储在一个连续的3 2 位 寄存内:双精度浮点数的偏移指数为l l 位,符号位为l 位,尾数为5 2 位。无 论单精度浮点数还是双精度浮点数,它们的能够表示的浮点数范围都是有限的。 在实际的浮点运算中,经常会出现指数溢出和舍入误差等问题。指数溢出 武汉理工大学硕士学位论文 是指浮点运算过程中,指数大于或者小于允许指数值时所造成的溢出;当结果 的指数大于允许指数时,就会发生指数上溢;当指数大于或者小于最小允许指 数时,就发生指数下溢;由于浮点数的尾数位是有限的,所以存储时会产生舍 入误差,每次运算又会产生新的截断误差。当采用累加或累乘的方法进行数值 计算时,误差的累积可能使最后的计算结果变成没有意义的值。即使在常规计 算中也会出现超出常规的事情,即病态条件,例如在求解反问题的过程中通常 会遇到病态矩阵等问题,即使使用扩展双精度浮点数也无法绕过这个问题,只 能采用超高精度的浮点运算来解决这些问题。 一些组织和个人相继推出了超高精度的浮点函数运算库,仅c 和c + + 语言 开发出了b l i t z 斗斗、p o o m a 、m t l 、c g a l 、i m s l 、g m p 等等,尤其是g m p 库,宣称自己是目前最快的高精度数值运算库。这些运算库均采用数组来存储 浮点数,通过软件的方式模拟出高精度浮点运算。 这些运算库虽然功能强大,但是有几个明显的问题使得它们并不方便使用, 首先,使用这些库前均需要用户进行下载,在本机上进行编译和安装,对于那 些并不擅长于编译程序库、或者本地环境无法满足编译安装条件的用户来说, 无疑是非常痛苦的;其次,使用这些浮点运算库开发出来的程序移植性并不好, 在那些没有安装相应浮点库的机器上无法正确的运行;最后,由于计算机之间 硬件环境的不同( 比如,机器的内存大小或者c p u 位数不同) ,某些机器上能 够正常运行的程序在其他机器上运行时也许会得到不同的结果。 随着互联网技术的发展以及网络环境的改善,w e b 应用程序开始在国民的 学习、生活、工作、交易以及娱乐中扮演越来越重要的使用。相对于传统的本 地应用程序,w e b 应用程序要方便得多,不需要下载、配置、安装等,几乎不 会占用本机的存储资源,几乎不会受操作系统类型和版本的影响,用户只要能 够接入网络就能够享受到相关的服务。这些w e b 应用中,大家熟悉的有w e b q q 、 网络硬盘、网页版的网络游戏等等。w e b 应用程序有两种模式c s 、b s 。c s 是客户端朋及务器端程序,b s 就是浏览器端服务器端应用程序。c s 模式需要 指定的客户端程序来连接到服务器端,b s 模式的用户一般只用借助于浏览器 就能够享受到相应的服务。 正在因为w e b 应用的范围越来越广泛,所以可以将超高精度浮点运算库也 移植为成w e b 应用程序,从而摆脱对操作系统和硬件平台的依赖,减轻使用者 的工作量。 2 武汉理工大学硕士学位论文 1 2 课题主要的研究内容 本课题主要研究以下几个方面的内容: 1 ) 超高精度浮点运算的解析。对现有的超高精度浮点运算库进行了封装, 对字符串形式的浮点运算进行解析并得出运算结果。 2 ) 跨平台高性能i o 模式的设计。主要研究如何将e p o l l 和i o c p 统一到 相同的网络i o 设计模式内,并通过统一的接口实现真正的可移植开发。 3 ) 浮点运算服务器组的分布式设计。对服务器端进行分布式拓扑结构设 计,将不同的功能划分到不同的服务器上,能够通过增加服务器的数量来提升 整个服务器组的性能。 1 3 作者的工作和论文结构 本文由以下几个部分组成: 第2 章一些预备知识的介绍。包含两方面的内容:仿函数的优点以及应用, c 1 0 k 问题的解决办法。指出仿函数相对于函数和函数指针有哪些优点,演示 了如何将仿函数应用到面向接口编程中,指出了c i o k 出现的原因,以及在 w i n d o w s 和l i n u x 平台下如何解决c 1 0 k 问题。 第3 章实现了超高精度浮点运算解析器实现和分布式服务器组的设计。利 用b o o s t 提供的小型解析器b o o s t :s p i f i t 实现了一个小型的解析器。通过对服务 器端的功能进行划分,让不同的进程负责不同的功能,设计出服务器端的详细 拓扑结构。 第4 章对服务器端的层次进行详细的划分,并实现各个层次的功能。给出 了详细的网络层设计方案,提出了一种跨平台的高性能i o 设计模式。通过对 两种高性能网络i o 设计模式r e a c t o r 和p r o a c t o r 进行分析,最终将它们统一在 “模拟”的p o r t a b l e p r o a c t o r 模型内,在l i n t l x 平台和w i n d o w s 平台分别对印o i l 和i o c p 进行封装并且实现了p o r t a b l c p r o a c t o r 模型。 第5 章对本文实现的功能进行了测试和总结。 3 武汉理工大学硕士学位论文 绍。 第2 章预备知识 为更好地阐述研究的课题,先对课题所涉及的仿函数和c i o k 问题进行介 2 1 仿函数 2 1 1 采用仿函数的原因 函数对象,又称仿函划2 1 ,意思是一个对象表现得像函数,这是c + + 语言 的特性。如果一个类型定义了“函数调用运算符,那么它就可以被称作仿函数, 它的对象就能够像普通函数一样被调用。 在说明仿函数对于普通函数的优点之前,先看一个仿函数对象的实例: 图2 - 1 一个简单的仿函数示例 图2 1 中的f u n c t o r 就是一个仿函数类型,它的对象f u n c t o r 能够像普通的 函数一样被调用。 仿函数表面上和函数十分相似,但是由于它拥有一些非常明显优点所以在 c + + 标准库内,仿函数有着广泛的应用f 3 4 5 1 。c + + 标准库预定义了一些实用的函 数对象,包括算术运算、关系运算和逻辑运算等,这些函数对象经常作为参数, 传递给标准库的一些算法,比如s t d :s o r t , s t d :f o re a c h 等。 4 武汉理工大学硕士学位论文 由于仿函数是类类型,所以仿函数既具有函数的功能,又拥有类的优点: 能够继承、泛化、拥有自己的成员等等,所以仿函数具有以下的优点: 1 ) 仿函数类型可以拥有成员变量和成员函数的。意味着仿函数就可以获得“状 态 ,从而实现了更高的灵活性。 2 ) 仿函数拥有自己的型别。尽管函数也自己的类型,但是它的类型却有诸多限 制,普通函数指针和类的成员函数指针就是完全不同的类型,有些地方传递 仿函数对象比传递函数或者函数指针要方便得多。 3 ) 仿函数在某些情况下具有比普通函数更快的执行速度。仿函数可以在某些普 通函数无法内联展开的场合展开,所以仿函数在效率上可能会更高。 2 1 2 仿函数的特点 2 1 2 1 仿函数同样可以作为回调函数 回调函数网是指程序员不能显式调用函数,必须在程序运行后将回调函数 的地址作为实参传递给调用接口来达到回调的目的。传递函数指针是事件驱动 系统中常用的方式,在使用函数指针作为回调函数的话,必须先确保函数指针 的返回类型和形参列表必须和回调函数定义的接口吻合。如图2 2 所示: 图2 - 2 使用函数指针作为回调函数的接口 当以函数指针作为回调函数时,接口的定义方式比较复杂,必须同时指明 函数指针的返回值类型和形参列表,这也是许多程序设计人员不喜欢使用函数 指针的原因。 由于类类型通过重载“o p e r a t o r0 ”操作符,就可以成为仿函数,从而拥有 与函数相同的功能,因此可以考虑通过传递仿函数对象来代替传递函数指针, 直接使用仿函数作为回调函数,如图2 3 所示。 5 武汉理工大学硕士学位论文 图2 - 3 使用仿函数作为回调函数 任何a 类型的对象,都可以作为实参传递给c a l lb a c k 接口,而不用担心 在传递函数指针时出现的类型不吻合问题。另外,作为回调函数时,仿函数比 函数指针更为简洁,仅仅使用一个仿函数的类类型就可以取代函数指针需要的 返回值类型以及形参类型列表。 图2 4 重载o p e r a t o r0 操作符 因为仿函数是类类型,它具有c + + 类类型的一切特点。如果将仿函数定义 为基类,将“o p e r a t o r0 声明为虚函数,在子类中实现可以获得多态的效果, 这样就能在语法上获得更灵活的提升。如图2 _ 4 所示。 a c t i o n 是仿函数的基类,表示用户的操作。p r e s s b u t t o n 、c l o s e w i n d o w $ 和 m o v e w i n d o w s 类均继承自a c t i o n 类,并对“o p e r a t o r0 进行了重载,分别表 示按下按钮、关闭窗口和移动窗口的操作。对于以a c t i o n 对象为回调函数的接 口,就可以利用多态来调用不同的功能,如图2 5 所示。 6 武汉理工大学硕士学位论文 图2 - 5 仿函数的多态调用 当需要添加新的功能时,并不需要直接修改接口,只需要定义从a c t i o n 继承并实现了“o p e r a t o r0 操作符的子类。所以,当使用仿函数作为回调函 数时,比以函数指针作为回调函数在语法上更为简便,也更容易通过继承等方 图2 - 6 使用仿函数作为回调函数 7 武汉理工大学硕士学位论文 2 1 2 2 仿函数作为回调函数具有更好的性能 由上一节可知,函数指针和仿函数对象均可以作为实参传递给相应的接口, 以此实现函数回调的目的。在某些情况下,仿函数的性能更为出色,这是因为 c + + 编译能够内联函数对象,如图2 6 所示。 以仿函数作为回调函数的s o r t ( c o m p a r e r o ) 算法的效率要比以函数指针作为 回调函数的s o r t ( c o m p a r e ) 效率要高,主要原因是回调函数作为一个函数指针传 入时代码无法进行展开,而仿函数则不同。虽然s o r t 本身并不能展开,但是s o r t 函数中对仿函数的调用是在编译期就能够确定并进行内联展开的。 当仿函数能够内联展开时,使用仿函数作为回调函数比使用函数指针作为 回调函数性能更优。 2 1 2 3 类的成员函数指针使用复杂 函数指针不仅包括普通的函数指针还包含类的成员函数指针。类的成员函 数指针和普通函数指针是完全不同的指针类型,它们之间无法互相进行强制转 化。例如,对于返回类型为v o i d ,形参列表为( i n t ,i n t ) 类型的函数,它的函数 指针定义形式如下, v o i d ( 枣) ( i i i t ,i n t ) ; 如果这个函数定义在类型a 的内部,那么它的指针类型除了必要的返回类 型和形参列表外,还必须附带上所属类类型的信息, v o i d ( a :幸) ( i n 4i n t ) = 很明显,即使返回类型和形参相同的,成员函数指针要比普通函数指针多 出一个类类型信息。并且成员函数指针只能指向特定类型的成员函数。表2 一l 演示了定义和使用函数指针以及成员函数指针的方法。 对于以函数指针作为参数的函数c a l l 可以接受s o m f u n 作为实参,却无法 接受& o b ja :i n v o k e 。解决办法之一就是在类型a 内添加友员函数,通过友员 函数间接的调用类型a 的成员函数i n v o k e 来达到到将成员函数转化为普通函数 的目的,如图2 7 所示。 8 武汉理i t 大学硕士学位论文 表2 - 1 函数指针和成员函数指针的定义和使用 ? 普通函数指针成员函数指针 : : t y p c d e fv o i d ( 宰f u n p t r ) ( i n t ,i n o ; s t r u c t a v o i di n v o k e ( i 咄h a t ) ; ) ; t y p e d e f v o i d ( a :m e m f u n p t r ) ( i n t ,i n t ) ; v o i ds o m f u n ( i n t ,i n t ) ; a o b j _ a ; f u n p t rp t r = s o m e _ f u n ;m e m u n p t rp t r = & a :i n v o k e ; ( * p t r ) ( 1 0 ,11 ) ;( o b j - a 木p t r ) ( 1 0 ,1 1 ) ; v o i dc a l l ( v o i d ( 木f ) ( i n t ,i n t ) ,i n ta ,i mb ) ; c a l l ( s o m e f u n ,10 ,11 ) ;r i g h t c a l l ( & o b ja :s o m f u n ,1 0 ,1 1 ) ;w r o n g 图2 - 7 使用友元函数来传递成员函数指针 虽然达到了传递成员函数指针的目的,但是这并不是一种好的解决方法, 1 ) 友员是一种比继承更强的耦合关系,它能够随意的访问私有成员和函数, 修改类的成员变量,打破了封装; 2 ) 如果为每个需要传递的成员函数都设计一个友员函数,肯定会增加代码的 复杂度,增加代码维护的工作量。 2 1 2 4 仿函数可以保存函数指针和函数的实参 仿函数可以拥有自己的成员变量和成员函数,可以拥有自身的状态。因此, 可以将函数指针和函数实参作为成员存储在仿函数内部,在仿函数被调用时再 将它们组合起来进行使用,如表2 2 所示: 9 武汉理工大学硕士学位论文 表2 2 使用仿函数保存函数指针 了保存普通函数指针的仿函数保存函数成员函数指针的仿函数! t e m p l a t e t e m p l a t e s t r u c tb i n d ts t r u c tb i n d t t y p e d e fr ( * f u n p t r ) ( a 0 ) ;t y p e d e f r ( t :f u n p t o ( a o ) ; r o p e r a t o r o0 r o p e r a t o r ( ) 0 r e t u r n _ p f ( _ a r 9 1 ) ;r e t u r n _ o b j 一 宰p 以盯9 1 ) ; ) f u n p t r _ p f ;普通函数指针f u n p t r _ p f ;成员函数指针 a o _ a r 9 1 ;函数实参 a o _ a r g l ;实参 ) ;t 事o b j ;类对象的实参 ; 在表2 2 中,r 是返回类型,a o 是形参,t 是类类型。可以通过模板的特 化技术,使用相同的类型同时保存普通函数的指针和成员函数的指针。这时, b i n dt 就不仅可以保存普通函数指针,还可以保存成员函数指针和它们的实参。 表2 - 3 使用b i n d 操作绑定函数的实参 仿函数对象f u n c t o r l 和f u n c t o r 2 类型相同仿函数对象f u n c t o r l 和f u n c t o r 2 类型相同 s t d :t r l :f u n c t i o n f u n c t o r l ,f u n c t o r 2 ;s t d :t r l :f u n c t i o n f u n c t o r l ,f u n c t o r 2 ; 使用s o m f u n 和a :i n v o k e 对它们进行初始化: 使用s o m f u n 和a :i n v o k e 对它们进行初始化: f u n c t o r l = b i n d ( s o m f u n , - l ,j ) ; f u n e t o r l = b i n d ( s o m f u n , 1 0 ,1 2 ) ; f u n c t o r 2 = b i n d ( & a :s o m f u n , - l ,- 2 ) ; f u n c t o r 2 = b i n d ( & a :s o m f u n , ll ,2 ) ; 在内部调用的实际上是s o m f u n ( 1o ,1 1 )在内部调用的实际上是s o m f u a ( 1 0 ,1 2 ) f u n c t o r l ( 1 0 ,1 1 ) ; f u n c t o r l0 ; 在内部调用的实际上就是o b j 一 i n v o k e ( 1 0 ,1 1 )在内部调用的实际上就是o b j i n v o k e ( 1 1 ,2 ) f u n c t o r 2 ( 1 0 ,“) ;f u n c t o r 2 ( ) ; 随着c + + o x 最新标准 7 , 8 1 的出台,c + + 标准库已经正式引入了t r l :b i n d ( 绑 定操作符) 和t r l :f u n c t i o n ( 仿函数类型) ,利用t r l :b i n d ,用户可以直接将函数 指针、成员函数指针、函数的实参保存到相同的t r l :f u n c t i o n 对象内,如表2 3 所示,o b j 是a 类型的一个对象,l 和2 为占位符,表示该位置上的实参并不 确定,可以在仿函数被调用时再确定。 既然普通函数、类成员函数、函数的实参可以绑定到相同的仿函数类型上, 那么: 1 ) 可以使用仿函数类型作为形参,直接使用b i n d 操作结合仿函数来传递函数 l o 武汉理工大学硕士学位论文 指针和类的成员函数指针。 图2 - 8 使用仿函数类型代替指针类型 图2 8 中,使用仿函数作为形参类型,使用容器保存仿函数。这样做有两 个很明显的好处: 1 ) 普通函数指针和成员函数指针均可以放在相同类型的仿函数对象内,这样从 普通函数指针和类的成员函数指针在语法层面上获得了统一,可以通过相同 的数据结构保存和传递。 2 ) 简化接口的设计,不需要为类的成员函数指针添加额外的代码,完全屏蔽了 函数指针的调用。 s t d :t r l 的b i n d 一共定义了九个占位符,1 、2 、3 、4 、5 、6 、7 、8 和9 ,这意味着,b i n d 可以绑定最多九个形参到相应的仿函数对象上,在实 际的应用程序中,很少有超过9 个形参的函数,完全能够满足目前的程序设计 要求。 综上所述,仿函数作为回调函数时比函数指针更为简洁,能够获得更好的 性能;借助t r l :b i n d 的绑定操作,可以将不同类型的函数指针保存到相同的仿 函数类型内;仿函数能够保存函数指针、能够保存函数的形参列表、能够保存 函数的实参,这是仿函数相对于函数指针最大的优势。在应用到程序设计中, 如果需要传递函数指针,可以使用仿函数进行代替,可以大大减少程序的复杂 度和出错机率。 2 2 基于仿函数的面向接口编程 面向接口编程9 1 0 1 的含义是指在系统分析和架构中,分清层次和依赖关系, 每个层次不是直接向其上层提供服务( 即不是直接实例化在上层中) ,而是通过 武汉理工大学硕士学位论文 定义一组接口,仅向上层提供接口,上层对于下层仅仅是接口依赖,而不依赖 具体类【l l 】。 这样做能增强系统的灵活性:当下层需要改变时,只要接口及接口功能不 变,则上层不用做任何修改;甚至可以在不改动上层代码时将下层整个替换掉。 表2 4 使用虚函数和仿函数实现的策略模式( s t r a t e g y ) 常规设计基于仿函数 s t r u c ti p e l s o ns t r u c ti p e r s o n v i r t u a lv o i dw a l k ( ) = o ; v o i d w a l k 0 ) ; w a l k ( ) ; s t r u c tm a n :p u b l i ci p e r s o n ) f u n c t i o n w a l k ; v o i dw a l k o ; ) ; ) v o i dm a n w a l k o ; s t r u c tw o m a n :p u b l i ci p e r s o nv o i dw o m a n w a l k o ; v o i dw a l k ( ) ;i p e r s o nm a n ,w o m a n ; m a n w a l k = b i n d ( m a n w a l k ) ; w o m a n w a l k = b i n d ( w o m a n w a l k ) ; i p e r s o n m a n = n e wm a n ; m a n w a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年期货从业资格考试期货市场投资分析与试题
- 2025年事业单位教师招聘考试物理学科专业知识试卷(物理教学设计)
- 2025年学历类自考专业(行政管理)社会学概论-法学概论参考题库含答案解析(5卷)
- 2025年学历类自考专业(行政管理)法学概论-公务员制度参考题库含答案解析(5卷)
- 2025年学历类自考专业(行政管理)政治学概论-公文写作与处理参考题库含答案解析(5卷)
- (2024年秋季版)七年级道德与法治下册 第一单元 我是自己的主人 第一课 你会玩吗 第2框 我们有权利玩说课稿 人民版
- 软件开发项目需求调研及方案设计
- 3.1.2铁的重要化合物 教学设计 2024-2025学年高一上学期化学人教版(2019)必修第一册
- 2025年学历类自考专业(英语)语言与文化-现代英语语法参考题库含答案解析(5卷)
- Module 12 Save our world Unit 3 说课稿 2024-2025学年外研版英语九年级上册
- 2025年《党政机关厉行节约反对浪费条例》应知应会测试考试题库
- 2024-2025学年渤海船舶职业学院单招《语文》题库试题带答案详解(培优A卷)
- 2025年川教版(2024)小学信息科技三年级(上册)教学设计及反思(附目录P118)
- 智能制造装备产业“十五五”发展规划公布
- 《小学教师专业发展》课件-第四章 教师的自我发展
- 企业ESG表现与其韧性之间的关联研究:以厚德方能行稳致远为视角的探索分析
- 2025-2030中国魔芋胶行业营销渠道与重点企业发展分析报告
- 小学生书法课件模板
- 幼儿园小班家长会课件图片
- 养老院租赁合同协议书
- 个人车位租赁合同(含充电桩安装)
评论
0/150
提交评论