我们已看到用COM服务器组件对于建立一个基于网络的应用程序的重要性,但问题不在于是否建立它们,而在于用什么语言去创建。一种选择是用C++。
人们对C++有许多不同的看法,保守的C++程序员坚持用其他语言创建COM组件,他们认为只有真正的程序员使用C++。另一方面,VB程序员认为C++是一种很难把握和使用的语言,没有必要增加编程时间和进行艰难的尝试。Java程序员认为他们比C++程序员强,因为James Gosling(Java的发明者)吸收了许多语言(包括C++ )的优点发明了Java,本章和下一章的目的就是消除对C++的偏见和错误概念。
本章集中介绍用C++ 建立服务器组件,不讲述C++语言,假如想学C++ ,请参阅Ivor.Horton著的《Beginning Visual C++6》,Wrox 出版,书号为ISBN 1-861000-88-X。
本章的主要内容有:
? C++简史。
? 使用C++原因。
? 从VB移植到C++。
? ATL、STL和MFC介绍。
? 建立一个COM组件。
? 错误处理与调试。
更重要的是应该记住,现在,不只是在用C++建立组件,可以使用Visual C++中可用的任何工具,使得建立过程更加轻易。先从C++的起源谈起。
17.1 C++语言
在决定是否使用C++语言之前,最好是搞清楚这种语言的实质,让我们看一下C++的历史和现状。
17.1.1 C++简史
刚开始形成的是C语言,那些想建立更快更有效的代码的程序员非常欣赏C语言,有一位名叫Bjarne Stroustrup的人却不满足于仅仅是生产快速代码,他想创建面向对象的C语言编程。他开始对C语言的内核进行必要的修改,使其能满足面向对象模型的要求。C++从此产生。
Bjarne Stroustrup是C++的最初设计者和实现者。它自诞生以来,经过开发和扩充已成一种完全成熟的编程语言。现在C++已由ANSI、BSI、DIN、其他几个国家标准机构和ISO定为标准。ISO标准于1997年11月4日经投票正式通过。
C++标准演变了许多年。C++模板是近几年来对此语言的一种扩展,模板是根据类型参数来产生函数和类的机制,有时也称模板为“参数化的类型”。使用模板,可以设计一个对许多类型的数据进行操作的类,而不需要为每个类型的数据建立一个单独的类。标准模板库(Standard Tempalte Library,STL )和微软的活动模板库(Active Tempalte Library,ATL )都基于这个C++语言扩展。
C++标准可分为两部分, C++语言本身和C++标准库。C++标准库对于Visual C++是相当新的,实际上微软只是在发布Visual C++ 5.0时去除了一些“bug”。标准库提供了标准的输入/输出、字符串、容器(如矢量、列表和映射等)、非数值运算(如排序、搜索和合并等)和对数值计算的支持。应该说, C/C++包含了相对少的要害字,而且很多最有用的函数都来源于库,C++标准库实现容器和算法的部分就是STL。
STL是数据结构和算法的一个框架,数据结构包括矢量、列表和映射等,算法包括这些数据结构的查找、拷贝和排序等。1994年7月,ANSI/ISO C++标准委员会投票决定接受STL为C++标准库的一部分,这个建议是根据Alex Stepanov、Meng Lee和David Musser这三人的编程和软件库研究提出的。STL的产生是为了满足通用性的设计目标,而不是为了提高性能。
那么微软对C++标准的态度怎什么样?微软运行VC++与Plum-Hall C++,想比较得到的分数在92%和93%之间。为什么不是100%的一个原因是跟踪这个标准并同时建立一个编译器比较困难,微软也考虑了对现有编码兼容的重要性,有时他们不得不偏离标准以保持这个兼容性。
17.1.2 使用C++的原因
应该有充分的理由使用C++创建服务器组件,而不只是为了给上司一个好印象才使用C++。假如以前没用过C++,你必须要尽力学习。
1. 性能
性能有个两方面,算法速度和机器代码效率。一个算法可以定义为数据通过系统的概念化的路径,它描述一些点,在这些点上,数据能够被操作并可转换产生某个结果。例如,一个算法定义为获取一个字符串,计算字符串中的字符个数,并作为结果返回的过程。算法与
语言是独立的,所以在编程之前必须设计算法,编写一个快速程序的第一个步骤是设计良好的算法,能以最少的操作步骤得出问题的答案。第二个步是选择语言,这也影响程序的速度。
从性能的角度考虑,用汇编语言编写程序是最佳的选择,它是计算机能理解的自然语言。但是,几乎没有人用汇编语言编写完整的程序,因为这样做极其乏味。另一个最佳的选择是C语言。然而,由VC++提供的所有工具都产生C++,而不是C。使用VC++的向导可以生成大量的使用代码,而不必人工地编写代码。从编写程序的难易程度和程序的性能综合考虑, C++是最佳的选择。
C++性能良好,因为它被编译为机器代码。对于VBScript和Java等语言,代码在运行时由程序解释,而且每次运行程序时都要将代码转换为机器码,这样做效率比较低,不仅仅是已编译过的C++程序运行得较快,而且微软C++编译器已存在多年。这意味着微软的编译器程序员已经把许多优点集中到编译器上,以致于它能产生非常高效的机器码。因为C++是编译语言,而且非常自然,比VB更接近机器代码,所以由C++编译器产生的代码一定比VB的编译代码效率更高。
2. 错误处理
一个好的程序与一个伟大的程序的区别就是其是否具有良好的错误处理支持。实际上,假如在实现中首先进行错误处理,而不是在最后才进行,那么整个程序的开发和测试过程会更加完美。但是,错误处理只能与语言所支持的内容相一致。
VBScript具有基本的错误处理支持功能。在默认情况下,不能捕捉VBScript中的错误。每次怀疑产生错误时,要调用On Error Resume Next功能,并检查Error对象。
而C++中的错误处理比较好,这是因为有“异常处理”,本章的后面部分将具体介绍。
3. 最小的依靠性
正如上面所说,C++是一种编译语言,即C++代码在执行之前已转换为机器码。只要此代码不依靠于外部的动态链接库(DLL),C++就可以在不需要安装额外程序的情况下移动到运行同样操作系统的其他机器和微处理器上,而移动Java程序时需要先安装Java运行期库。
4. 利用现有的代码
由于C和C++已经存在许多年了,现在有许多可利用的代码,你的服务器组件可以使用现有的C/C++代码或库。例如统计库和到老系统的C接口。
5. 最大化COM特征
COM与C++很接近,实际上, Don Box(COM的权威)在他的《Essential COM》一书的第一章写道:“COM就是更好的C++”。他说明了COM规范是如何从C++语言规律中产生出来的。通过理解C++,会对COM有更深的理解。
某些语言不能利用所有的COM特征,而在C++中,几乎可以使用所有的COM特征。
17.1.3 不使用C++的原因
知道什么时候使用C++是重要的,同样,知道什么时候不使用C++也是重要的。想像一下那些长期维护代码的人,假如他们中没有一些C++程序员支持C++,那么开发者们不得不把眼光转向另外一些他们熟悉的语言。
改变C++组件时,为了看到这些改变的结果,必须重新编译该组件代码,这会花费很长的开发时间。C++不能像ASP页面代码那样,只使用记事本,改变代码的一行,重新装载而得到结果。因此,假如某些工作需要经常变化(如原型),不要用C++。
在C++中,对一些致命的错误不能获得更多的保护,写一个使组件崩溃的代码是很轻易的。这是为了提供快速代码而付出的代价, C++不会停下来去检查代码是否按设计运行能否使程序不崩溃依靠于开发者的技巧。假如在这方面花的时间较少或刚刚学习C++,最好不要使用C++。等到已经意识到C++中所有轻易犯的错误,而且在检测组件之前花了许多时间,才可以使用C++,假如想很快、很轻易地建立一个组件,而且也不考虑该组件的执行速度,那么使用VB吧!
17.1.4 把ASP技巧转到C++上
学习新东西的最好方法就是利用现有的技巧。对于ASP开发者来说,已经学习了C++所要求的许多技巧,非凡是,JScript语法和ActiveX或COM的面向对象编程的概念。
1. JScript
大部分ASP开发者都用JScript在浏览器上使用DHtml。JScript的语法与C非常相似,所以,假如懂得JScript,那么就懂得基本的C语法。当然,只是C++语法的子集。C++有许多额外的语法来支持面向对象编程,这就是我们下一步要做的。
2. 面向对象编程
假如你在VB中使用过类(class),则对任何COM对象和文档对象模型(Document ObjectModel,DOM )都应熟悉,因为已经有了面向对象编程(OOP)的概念。在前面已经说过, C和C++的区别是C++支持面向对象编程。