background image

  最后,Visual C++的编译和连接时的错误信息比 Delphi 要详细和具体的多。特别是使用
ATL 开发更加如此。

应用框架:

MFC?有 KFC 流行吗?

  应用程序框架(Application Frame),有时也称为对象框架。Visual C++采用的框架是
MFC。MFC 不仅仅是人们通常理解的一个类库(同样,Delphi 的 VCL 也不仅仅是一个控件
库,尽管它的名字叫

"可视控件库")。你如果选择了 MFC,也就选择了一种程序结构,一种

编程风格。

MFC 早在 Windows 3.x 的时代就出现了,那时的 Visual C++还是 16 位的。经

过这些年的不断补充和完善,

MFC 已经十分成熟。但由于原型出现得比较早,MFC 相比

VCL 落后了一个时代。尽管微软对 MFC 的更新没有停止,我也经常读到"只要

Windows 不过时,MFC 就不会过时"之类观点的文章,但就象 Inprise(原 Borland)的 OWL
框架的淡出一样,

MFC 的淡出也是早晚的事。其实 MFC 是和 OWL 同一个时代的产物 。

OWL 已经不在了,MFC 怎能不"居安思危"呢?如果 MFC 青春永驻,微软的开发人员也
不会

"私自"开发出基于 ATL 的 WTL 呀。当然,WTL 的地位不能和 MFC 比,它并不是微软

官方支持的框架,封装的功能也相当有限。但至少也反衬出了

MFC 存在的不足。   

  我们以为,最能体现一个应用程序框架的先进性的是它的委托模型,即对 Windows 消
息的封装机制。对

Windows API 的封装就不用说了吧。大同小异,也没什么技术含量。如果

高兴,你也可以自己写一个类库来封装。但对

Windows 消息驱动机制的封装就不是那么容

易的了。最自然的封装方式是采用虚成员函数。如果要响应某个消息就重载相应的虚函数。
但出乎我的意料,

MFC 采用的是"古老"的宏定义方法。用宏定义方法的好处是省去了虚函

VTable 的系统开销(由于 Windows 的消息种类很多,开销不算太小)。不过带来的缺点

就是映射不太直观。对于

MFC,则是"太不直观"了。它的消息映射代码虽然是可见的,

"劝君莫碰"。好在 VC 的 ClassWizard 可以自动生成消息映射代码,使用起来还算方便。

但和

VCL 的委托模型相比,MFC 的映射方法就显得太落后了。而 Delphi 的 Object Pascal

因为没有

"标准负担",语言引入了组件、事件处理、属性等新特性。由于功夫做在编译器级,

生成的源代码就显得十分简洁。似乎

VC 是"让框架迁就语言",而 Delphi 是"让语言迁就框

"。   

  我想举一个对字符串操作的封装的例子来说明 MFC 和 VCL 的优缺点。在 MFC 中,
CStringList 类有加入、获取、删除等功能,但 VCL 的 TStringList 类除了上述功能还有排序、
从逗号分隔的字串读入、流输入输出等功能。但同样的字符串替换功能,

VCL 的

StringReplace 要比 MFC 的 CString::Replace 慢 2-3 倍。总的来说,VCL 的封装比 MFC
更为高层,更为抽象,但不可避免地带来的问题是某些部分执行效率比

MFC 略低。这就

象低级语言

(如汇编)的执行效率比高级语言(如 Basic)高,但编程效率较低。鱼和熊掌不可

兼得嘛。

   

  VCL 比之 MFC 的另一优点是对异常处理的支持,而一大缺点是对多线程支持差。VCL 的
大部分都不是针对多线程优化的。虽说

VCL 提供了简化多线程操作的类,但只是工作者线

(worker threads)使用起来比较简单。如果线程要和界面打交道的话事情就变得麻烦了,

因为除了应用程序的主线程,任何线程不能访问任何可视的

VCL 部件。你不得不使用

Synchronize 方法等待主线程处理它的消息,然后在主线程中访问 VCL 部件。而 MFC 就
没有这样的限制。