ImageVerifierCode 换一换
格式:DOCX , 页数:11 ,大小:33.86KB ,
资源ID:18195404      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/18195404.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(STL之父访谈录转载docWord文档格式.docx)为本站会员(b****3)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

STL之父访谈录转载docWord文档格式.docx

1、我在70年代末期在tecton上面所认识到了一个有趣的问题:被广泛接受的adt观念有着根本性的缺陷.人们通常认为adt的特点是只暴露对象行为特征,而将实现隐藏起来.一项操作的复杂度被认为是与实现相关的属性,所以抽象的时候应予忽略.我则认识到,在考虑一个(抽象)操作时,复杂度(或者至少是一般观念上的复杂度)必须被同时考虑在内.这一点现在已经成了gp的核心理念之一.例如一个抽象的栈stack类型,仅仅保证你push进去的东西可以随后被pop出来是不够的,同样极端重要的是,不管stack有多大,你的push操作必须能在常数时间内完成.如果我写了一个stack,每push一次就慢一点,那谁都不会用这个

2、烂玩艺.我们是要把实现和界面分开,但不能完全忽略复杂度.复杂度必须是,而且也确实是横陈于模块的使用者与实现者之间的不成文契约.adt观念的引入是为了允许软件模块相互可替换.但除非另一个模块的操作复杂度与这个模块类似,否则你肯定不愿意实现这种互换.如果我用另外一个模块替换原来的模块,并提供完全相同的接口和行为,但就是复杂度不同,那么用户肯定不高兴.就算我费尽口舌介绍那些抽象实现的优点,他肯定还是不乐意用.复杂度必须被认为是接口的一部分.1983年左右,我转往纽约布鲁克林技术大学任教.开始研究的是图的算法,主要的合作伙伴是现在ibm的aaron kershenbaum.他在图和网络算法方面是个专家

3、,我使他相信高序(high order)的思想和gp能够应用在图的算法中.他支持我与他合作开始把这些想法用于实际的网络算法.某些图的算法太复杂了,只进行过理论分析,从来没有实现过.他企图建立一个包含有高序的通用组件的工具箱,这样某些算法就可以实现了.我决定使用lisp语言的一个变种scheme语言来建立这样一个工具箱.我们俩建立了一个巨大的库,展示了各种编程技术.网络算法是首要目标.不久当时还在通用电器的david musser加了进来,开发了更多的组件,一个非常大的库.这个库供大学里的本科生使用,但从未商业化.在这项工作中,我了解到副效应是很重要的,不利用副效应,你根本没法进行图操作.你不能

4、每次修改一个端点(vertex)时都在图上兜圈子.所以,当时得到的经验是在实现通用算法时可以把高序技术和副效应结合起来.副效应不总是坏的,只有在被错误使用时才是.1985年夏,我回到通用电器讲授有关高序程序设计的课程.我展示了在构件复杂算法时这项技术的应用.有一个听课的人叫陈迩,当时是信息系统实验室的主任.他问我是否能用ada语言实现这些技术,形成一个工业强度的库,并表示可以提供支持.我是个穷助教,所以尽管我当时对于ada一无所知,我还是回答好的.我跟dave musser一起建立这个ad a库.这是很重要的一个时期,从象scheme那样的动态类型语言(dynamically typed la

5、nguage)转向ada这样的强类型语言,使我认识到了强类型的重要性.谁都知道强类型有助于纠错.我则发现在ada的通用编程中,强类型是获取设计思想的有力工具.它不仅是查错工具,而且是思想工具.这项工作给了我对于组件空间进行正交分解的观念.我认识到,软件组件各自属于不同的类别.oop的狂热支持者认为一切都是对象.但我在ada通用库的工作中认识到,这是不对的.二分查找就不是个对象,它是个算法.此外,我还认识到,通过将组件空间分解到几个不同的方向上,我们可以减少组件的数量,更重要的是,我们可以提供一个设计产品的概念框架.随后,我在贝尔实验室c+组中得到一份工作,专事库研究.他们问我能不能用c+做类似

6、的事.我那时还不懂c+,但当然,我说我行.可结果我不行,因为1987年时,c+中还没有模板,这玩意儿在通用编程中是个必需品.结果只好用继承来获取通用性,那显然不理想.直到现在c+继承机制也不大用在通用编程中,我们来说说为什么.很多人想用继承实现数据结构和容器类,结果几乎全部一败涂地.c+的继承机制及与之相关的编程风格有着戏剧性的局限.用这种方式进行通用编程,连等于判断这类的小问题都解决不了.如果你以x类作为基类,设计了一个虚函数operater=,接受一个x类对象,并由x派生类y,那么y的operator=是在拿y类对象与x类对象做比较.以动物为例,定义animal类,派生giraffe(长颈

7、鹿)类.定义一个成员函数mate(),实现与另一个哺乳动物的交配操作,返回一个animal对象.现在看看你的派生类giraffe,它当然也有一个mate()方法,结果一个长颈鹿同一个动物交配,返回一个动物对象.这成何体统?当然,对于c+程序员来说,交配函数没那么重要,可是operator=就很重要了.对付这种问题,你得使用模板.用模板机制,一切如愿.尽管没有模板,我还是搞出来一个巨大的算法库,后来成了unix system laboratory standard component library的一部分.在bell lab,我从象andy koenig,bjarne stroustrup(a

8、ndrew koenig,前iso c+标准化委员会主席;bjarne stroustrup,c+之父-译者)这类专家身上学到很多东西.我认识到c/c+的重要,它们的一些成功之处是不能被忽略的.特别是我发现指针是个好东东.我不是说空悬的指针,或是指向栈的指针.我是说指针这个一般观念.地址的观念被广泛使用着.没有指针我们就没法描述并行算法.我们现在来探讨一下为什么说c是一种伟大的语言.通常人们认为c是编程利器并且获得如此成功,是因为unix是用c写的.我不同意.计算机的体系结构是长时间发展演变的结果,不是哪一个聪明的人创造的.事实上是广大程序员在解决实际问题的过程中提出的要求推动了那些天才提出这

9、些体系.计算机经过多次进化,现在只需要处理字节地址索引的内存,线性地址空间和指针.这个进化结果是对于人们要求解决问题的自然反映.dennis ritchie天才的作品c,正反映了演化了30年的计算机的最小模型.c当时并不是什么利器.但是当计算机被用来处理各种问题时,作为最小模型的c成了一种非常强大的语言,在各个领域解决各种问题时都非常高效.这就是c可移植性的奥秘,c是所有计算机的最佳抽象模型,而且这种抽象确确实实是建立在实际的计算机,而不是假想的计算机上的.人们可以比较容易的理解c背后的机器模型,比理解ada和scheme语言背后的机器模型要容易的多.c的成功是因为c做了正确的事,不是因为at

10、&t的极力鼓吹和unix.c+的成功是因为bjarne stroustrup以c为出发点来改进c,引入更多的编程技术,但始终保持在c所定义的机器模型框架之内,而不是闭门造车地自己搞出一个新的机器模型来.c的机器模型非常简单.你拥有内存,对象保存在那里面,你又有指向连续内存空间的指针,很好理解.c+保留了这个模型,不过大大扩展了内存中对象的范畴,毕竟c的数据类型太有限了,它允许你建立新的类型结构,但不允许你定义类型方法.这限制了类型系统的能力.c+把c的机器模型扩展为真正类型系统.1988年我到惠普实验室从事通用库开发工作.但实际上好几年我都是在作磁盘驱动器.很有趣但跟gp毫不相关.92年我终于

11、回到了gp领域,实验室主任bill worley建立了一个算法研究项目,由我负责.那时候c+已经有模板了.我发现bjarne的模板设计方案是非常天才的.在bell lab时,我参加过有关模班设计的几个早期的讨论,跟bjarne吵得很凶,我认为c+的模板设计应该尽可能向ada的通用方案看齐.我想可能我吵得太凶了,结果bjarne决定坚决拒绝我的建议.我当时就认识到在c+中设置模板函数的必要性了,那时候好多人都觉得最好只有模板类.不过我觉得一个模板函数在使用之前必须先显式实例化,跟ada似的.bjarne死活不听我的,他把模板函数设计成可以用重载机制来隐式实例化.后来这个特别的技术在我的工作中变得

12、至关重要,我发现它容许我做很多在ada中不可能的任务.非常高兴bjarne当初没听我的.您是什么时候第一次构思stl的,最初的目的是什么?92年那个项目建立时由8个人,渐渐地人越来越少,最后剩下俩,我和李梦,而且李小姐是这个领域的新手.在她的专业研究中编译器是主要工作,不过她接受了gp研究的想法,并且坚信此项研究将带给软件开发一个大变化,要知道那时候有这个信念的认可是寥寥无几.没有她,我可不敢想象我能搞定stl,毕竟stl标着两个人的名字:stepanov和lee.我们写了一个庞大的库,庞大的代码量,庞大的数据结构组件,函数对象,适配器类,等等.可是虽然有很多代码,却没有文档.我们的工作被认为

13、是一个验证性项目,其目的是搞清楚到底能不能在使算法尽可能通用化的前提下仍然具有很高的效率.我们化了很多时间来比较,结果发现,我们算法不仅最通用,而且要率与手写代码一样高效,这种程序设计风格在性能上是不打折扣的!这个库在不断成长,但是很难说它是什么时候成为一个项目的.stl的诞生是好几件事情的机缘巧合才促成的.什么时候,什么原因促使您决定建议使stl成为ansi/iso标准c+一部分的?1993年夏,andy koenig跑到斯坦福来讲c+课,我把一些有关的材料给他看,我想他当时确实是很兴奋.他安排我9月到圣何塞给c+标准委员会做一个演讲.我演讲的题目是c+程序设计的科学,讲得很理论化,要点是存

14、在一些c+的基本元素所必须遵循的,有关基本操作的原则.我举了一些例子,比如构造函数,赋值操作,相等操作.作为一种语言,c+没有什么限制.你可以用operator=()来做乘法.但是相等操作就应该是相等操作.它要有自反性,a=a;它要有对称性,a=b则b=a;它还要有传递性.作为一个数学公理,相等操作对于其他操作是基本的要素.构造函数和相等操作之间的联系就有公理性的东西在里边.你用拷贝构造函数生成了一个新对象,那么这个对象和原来那个就应该是相等的.c+是没有做强行要求,但是这是我们都必须遵守这个规则.同样的,赋值操作也必须产生相等的对象.我展示了一些基本操作的公理,还讲了一点迭代子(iterat

15、or),以及一些通用算法怎样利用迭代子来工作.我觉得那是一个两小时的枯燥演讲,但却非常受欢迎.不过我那时并没有想把这个东西塞在标准里,它毕竟是太过先进的编程技术,大概还不适于出现在现实世界里,恐怕那些做实际工作的人对它没什么兴趣.我是在9月做这个演讲的,直到次年(1994)月,我都没往ansi标准上动过什么脑筋.1月6日,我收到andy koenig的一封信(他那时是标准文档项目编辑),信中说如果我希望stl成为标准库的一部分,可以在1月25日之前提交一份建议到委员会.我的答复是:andy,你发疯了吗?,他答复道:不错,是的我发疯了,为什么咱们不疯一次试试看?当时我们有很多代码,但是没有文档,

16、更没有正式的建议书.李小姐和我每星期工作80小时,终于在期限之前写出一份正式的建议书.当是时也,只有andy一个人知道可能会发生些什么.他是唯一的支持者,在那段日子里他确实提供了很多帮助.我们把建议寄出去了,然后就是等待.在写建议的过程中我们做了很多事.当你把一个东西写下来,特别是想到你写的可能会成为标准,你就会发现设计中的所有纰漏.寄出标准后,我们不得不一段一段重写了库中间的代码,以及几百个组件,一直到3月份圣迭戈会议之前.然后我们又重新修订了建议书,因为在重新写代码的过程中,我们又发现建议书中间的很多瑕疵.您能描述一下当时委员会里的争论吗?建议一开始是被支持呢,还是反对?我当时无法预料会发

17、生些什么.我做了一个报告,反响很好.但当时有许多反对意见.主要的意见是:这是一份庞大的建议,而且来得太晚,前一次会议上已经做出决议,不在接受任何大的建议.而这个东西是有史以来最大的建议,包括了一大堆新玩艺.投票的结果很有趣,压倒多数的意见认为应对建议进行再考虑,并把投票推迟到下次会议,就是后来众所周知的滑铁卢会议.bjarne stroustrup成了stl的强有力支持者.很多人都通过建议、更改和修订的方式给予了帮助。bjarne干脆跑到这来跟我们一起工作了一个礼拜。andy更是无时无刻的帮助我们。c+是一种复杂的语言,不是总能搞得清楚确切的含义的。差不多每天我都要问andy和bjarne c

18、+能不能干这干那。我得把特殊的荣誉归于andy,是他提出把stl作为c+标准库的一部分;而bjarne也成了委员会中stl的主要鼓吹者。其他要感谢的人还有:mike vilot,标准库小组的负责人;rogue wave公司的nathan myers(rogue wave是boland c+builder中stl方案的提供商-译者),andersen咨询公司的larry podmolik。确实有好多人要致谢。在圣迭戈提出的stl实际与当时的c+,我们被要求用新的ansi/iso c+语言特性重写stl,这些特性中有一些是尚未实现的。为了正确使用这些新的、未实现的c+特性,bjarne和andy花

19、了无以计数的时间来帮助我们。人们希望容器独立于内存模式,这有点过分,因为语言本身并没有包括内存模式。所以我们得要想出一些机制来抽象内存模式。在stl的早期版本里,假定容器的容积可以用size_t类型来表示,迭代子之间的距离可以用ptrdiff_t来表示。现在我们被告知,你为什么不抽象的定义这些类型?这个要求比较高,连语言本身都没有抽象定义这些类型,而且c/c+数组还不能被这些类型定义所限定。我们发明了一个机制称作allocator,封装了内存模式的信息。这个机制深刻地影响了库中间的每一个组件。你可能疑惑:内存模式和算法或者容器类接口有什么关系?如果你使用size_t这样的东西,你就无法使用t*

20、对象,因为存在不同的指针类型(t*,t huge*,等等)。这样你就不能使用引用,因为内存模式不同的话,会产成不同的引用类型。这样就会导致标准库产生庞大的分支。另外一件重要的事情是我们原先的关联类型数据结构被扩展了。这比较容易一些,但是最为标准的东西总是很困难的,因为我们做的东西人们要使用很多年。从容器的观点看,stl做了十分清楚的二分法设计。所有的容器类被分成两种:顺序的和关联的,就好像常规的内存和按内容寻址的内存一般。这些容器的语义十分清楚。当我到滑铁卢以后,bjarne用了不少时间来安慰我不要太在意成败与否,因为虽然看上去似乎不会成功,但是我们毕竟做到了最好。我们试过了,所以应该坦然面对

21、。成功的期望很低。我们估计大部分的意见将是反对。但是事实上,确实有一些反对意见,但不占上风。滑铁卢投票的结果让人大跌眼镜,80%赞成,20%反对。所有人都预期会有一场恶战,一场大论战。结果是确实有争论,但投票是压倒性的。stl对于1994年2月发行的ansi/iso c+工作文件中的类库有何影响?stl被放进了滑铁卢会议的工作文件里。stl文档被分解成若干部分,放在了文件的不同部分中。mike vilot负责此事。我并没有过多地参与编辑工作,甚至也不是c+委员会的成员。不过每次有关stl的建议都由我来考虑。委员会考虑还是满周到的。委员会后来又做了一些有关模板机制的改动,哪些影响到了stl?在s

22、tl被接受之前,有两个变化影响到了我们修订stl。其一是模板类增加了包含模板函数的能力。stl广泛地使用了这个特性来允许你建立各种容纳容器的容器。一个单独的构造函数就能让你建立一个能容纳list或其他容器的vector。还有一个模板构造函数,从迭代子构造容器对象,你可以用一对迭代子当作参数传给它,这对迭代子之间的元素都会被用来构造新的容器类对象。另一个stl用到的新特性是把模板自身当作模板参数传给模板类。这项技术被用在刚刚提到的allocator中。那么stl影响了模板机制吗?在弗基山谷的会议中,bjarne建议给模板增加一个局部特殊化(partial specialization)的特性。这

23、个特性可以让很多算法和类效率更高,但也会带来代码体积上的问题。我跟bjarne在这个建议上共同研究了一段时间,这个建议就是为了使stl更高效而提出的。我们来解释一下什么是。你现在有一个模板函数swap(t&,t&),用来交换两个参数。但是当t是某些特殊的类型参数时,你想做一些特殊的事情。例如对于swap(int&,int&),你想用一种特别的操作来交换数据。这一点在没有局部特殊化机制的情况下是不可能的。有了局部特殊化机制,你可以声明一个模板函数如下:template class tvoid swap(vector t&,vector t&);这种形式给vector容器类的swap操作提供了一种

24、特别的办法。从性能的角度讲,这是非常重要的。如果你用通用的形式去交换vector,会使用三个赋值操作,vector被复制三次,时间复杂度是线性的。然而,如果我们有一个局部特殊化的swap版本专门用来交换两个vector,你可以得到一个时间复杂度为常数的,非常快的操作,只要移动vector头部的两个指针就ok。这能让vector上的sort算法运行得更快。没有局部特殊化,让某一种特殊的vector,例如vector int运行得更快的唯一办法是让程序员自己定一个特殊的swap函数,这行得通,但是加重了程序员的负担。在大部分情况下,局部特殊化机制能够让算法在某些通用类上表现得更高效。你有最通用的s

25、wap,不那么通用的swap,更不通用的swap,完全特殊的swap这么一系列重载的swap,然后你使用局部特殊化,编译器会自动找到最接近的那个swap。另一个例子copy。现在我们的copy就是通过迭代子一个一个地拷贝。使用模板特殊化可以定义一个模板函数:template class tt*copy(t*,t*,t*);这可以用memcpy高效地拷贝一系列指针来实现,因为是指针拷贝,我们可以不必担心构造对象和析构对象的开销。这个模板函数可以定义一次,然后供整个库使用,而且用户不必操心。我们使用局部特殊化处理了一些算法。这是个重要的改进,据我所知在弗基山谷会议上得到了好评,将来会成为标准的一部

26、分。(后来的确成了标准的一部分-译者)除了标准类库外,stl对那一类的应用程序来说最有用处?我希望stl能够引导大家学习一种新的编程风格:通用编程。我相信这种风格适用于任何种类的应用程序。这种风格就是:用最通用的方式来写算法和数据结构。这些结构所要求的语义特性应该能够被清楚地归类和分类,而这些归类分类的原则应该是任何对象都能满足的。理解和发展这种技术还要很长时间,stl不过是这个过程的起点。我们最终会对通用的组件有一个标准的分类,这些组件具有精心定义的接口和复杂度。程序员们将不必在微观层次上编程。你再也不用去写一个二分查找算法。就是在现在,stl也已经提供了好几个通用的二分查找算法,凡是能用二

27、分查找算法的场合,都可以使用这些算法。算法所要求的前提条件很少:你只要在代码里使用它。我希望所有的组件都能有这么一天。我们会有一个标准的分类,人们不用再重复这些工作。这就是douglas mcilroy的梦想,他在1969年关于构件工厂的那篇著名文章中所提出来的东西。stl就是这种的一个范例。当然,还需要有主流的力量介入这种技术的发展之中,光靠研究机构不行,工业界应该想程序员提供组件和工具,帮助他们找到所需的组件,把组件粘合到一起,然后确定复杂度是否达到预期。stl没有实现一个持久化(persistent)对象容器模型。map和multimap似乎是比较好的候选者,它们可以把对象按索引存入持久

28、对象数据库。您在此方向上做了什么工作吗,或者对这类实现有何评论?很多人都注意到这个问题。stl没实现持久化是有理由的。stl在当时已经是能被接受的最巨大的库了。再大一点的话,我认为委员会肯定不会接受。当然持久化是确实是一些人提出的问题。在设计stl,特别是设计allocator时,bjarne认为这个封装了内存模式的组件可以用来封装持久性内存模式。bjarne的洞察秋毫非常的重要和有趣,好几个对象数据库公司正在盯着这项技术。1994年10月我参加了object database management group的一个会议,我做了一个关于演说。他们非常感兴趣,想让他们正在形成中的组件库的接口与s

29、tl一致,但不包括allocator在内。不过该集团的某些成员仔细分析了allocator是否能够被用来实现持久化。我希望与stl接口一致的组件对象持久化方案能在接下来的一年里出现。set,multiset,map和multimap是用红黑树实现的,您试过用其他的结构,比如b*树来实现吗?我不认为b*适用于内存中的数据结构,不过当然这件事还是应该去做的。应该对许多其他的数据结构,比如跳表(skip list)、伸展树(splay tree)、半平衡树(half-balanced tree)等,也实现stl容器的标准接口。应该做这样的研究工作,因为stl提供了一个很好的框架,可以用来比较这些结构的性能。结口是固定的,基本的复杂度是固定的,现在我们就可一个对各种数据结构进行很有意义的比较了。在数据结构领域里有很多人用各种各样的接口来实现不同的数据结构,我希望他们能用stl框架来把这些数据结构变成通用的。(译者注:上面所提到的各种数据结构我以为大多并非急需,而一个stl没有提供而又是真正重要的数据结构是哈希结构。后来在stepanov和matt austern等人的sgi*stl中增补了hashset,hashmap和hashtable三种容器,使得这个stl实现才比较完满。众所周知,红黑树的时间复杂度为o(logn),而理想hash结构为o(1)。当然,如果实现了持久

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1