MFC和ATL的根本区别是什么?

假设我只是使用它们作为“正常”的GUI程序(没有COM,没有ActiveX,没有什么奇特的),我将在ATL和MFC之间看到的基本区别是什么,以帮助我找出使用哪一个?


我在网上做了一些search,但最终没有一个答案真的回答了我的问题:

  • http://msdn.microsoft.com/en-us/library/bk8ytxz5(v=vs.80).aspx :

    • “ATL是一种既快速又简单的方法,既可以在C ++中创build一个COM组件,又可以占用很小的空间。如果不需要MFC自动提供的所有内置function,可以使用ATL创build一个控件。

      没有真正回答我的问题,因为:

      • 我没有使用COM。

      • 这是否意味着MFC 不是很快? 为什么/怎么样?

    • “MFC允许您创build完整的应用程序,ActiveX控件和活动文档,如果您已经使用MFC创build了控件,则可能需要继续在MFC中进行开发。创build新控件时,如果您不需要使用ATL所有MFC的内置function“。

      也不回答我的问题,因为:

      • 我甚至不知道什么第一个ActiveX。

      • 看起来好像微软不鼓励使用MFC,但我不明白为什么。

      • 什么 ATL不提供的MFC的“内置function”?

    • 总的来说,这并不能回答我的问题,因为这并不能解释它们背后的缺点和原因。

因为直接或间接地,一切似乎都链接回上一页:

  • 我如何决定是否将ATL,MFC,Win32或CLR用于新的C ++项目?

    • “ATL&MFC在两者之间有点棘手。 [不要开玩笑!] 我会把你引到MSDN的页面来select它们之间的决定。

      显然 ,这不能回答我的问题。 🙂

  • http://www.codeguru.com/forum/archive/index.php/t-64778.html

  • 等等

目前观察到的 (在过去几天里,同时试图学习):

  • ATL基于模板或编译时多态。
    • ATL方法往往是非虚拟的,并倾向于返回引用。
  • MFC是基于虚拟方法,或者是运行时多态的。
    • MFC方法往往是虚拟的,并倾向于返回指针。

但是他们之间似乎没有任何架构上的区别

  • 两者都使用消息映射( BEGIN_MSG_MAPBEGIN_MESSAGE_MAP …大不了)
  • 都将Win32方法包装到类中
  • 两人似乎都有CWndCWindow类似

但是,如果除了编译时间和运行时间方面没有真正的差别,为什么它们都存在? 他们中的一个还不够吗?

我在这里错过了什么?

我认为,如果回顾一下这两个图书馆是如何通过时间起源和演变的,那么你的问题的答案大多是历史性的。

简短的回答是,如果你没有做任何“幻想”的事,请使用ATL。 COM引入的简单用户界面非常棒。

漫长的回答:MFC是在90年代初build立起来的,它试用了这种叫做C ++的新语言并将其应用到Windows。 当操作系统还没有这个function的时候,Office就像开发社区可以使用的function一样。

[编辑点缀:我没有在微软工作,所以我不知道Office是否构build在MFC上,但我认为答案是否定的。 回到Win 3.1,Win 95的时候,Office UI团队会发明新的控件,将它们打包到库中,然后Windows和MFC团队将包装器和API合并到那些带有可再发行dll的控件中。 我猜想这些团队之间有一些协作和代码共享。 最终,这些控件将使其进入Service Pack或下一个Windows版本的基本操作系统。 这种模式继续使用办公function区,它在Office发布之后作为附加组件joinWindows,现在成为Windows操作系统的一部分。]

那时图书馆是相当原始的,这既是因为C ++语言和编译器是新的,而且随着Office的发展,微软也随着时间的推移build立起来了。

由于这个历史,MFC:

  1. 有一个相当笨重的devise。 它开始作为一个围绕Windows API轻包装,但增长。 由于编译器和语言不支持它们,所以有一些小“特征”必须被发明出来。 他们没有模板,他们发明了一个string类,他们发明了列表类,他们devise了自己的运行时types标识等等。
  2. 封装20年的Office和Windows进化,其中包括你可能永远不会使用的东西的全部垃圾负载:单一和多个文档接口,DDE,COM,COM +,DCOM,文档链接和embedded(所以你可以embedded一个Word文档你的应用程序,如果你想),ActiveX控件(networking对象embedded的发展!),结构化文档存储,序列化和版本控制,自动化(从早期的VBA年),当然MVC。 最新版本支持Visual Studio风格的窗口停靠和Officefunction区。 基本上20年以来,雷德蒙德的每项技术都在某个地方。 这只是巨大的!
  3. 有大量的小问题,错误,解决方法,假设,支持那些你永远不会使用的东西,并且会导致问题。 你需要非常熟悉许多类的实现,以及它们如何相互作用以在体面的项目上使用它。 在debugging期间深入研究MFC源代码是很常见的。 find一个15年的旧技术说明一些指针为空导致崩溃仍然发生。 古文档embedded的初始化假设可能会以奇怪的方式影响您的应用程序。 在MFC中没有抽象的东西,你需要每天处理它的怪癖和内部,它不会隐藏任何东西。 不要让我开始上课向导。

ATL是随着C ++语言的发展而发明的,模板到达了。 ATL展示了如何使用模板来避免MFC库的运行时问题:

  1. 消息映射:由于它们是基于模板的,因此会检查types,并且如果拧紧了绑定函数,则不会生成。 在MFC中,消息映射是基于macros的,并且是运行时绑定的。 这可能导致奇怪的错误,消息路由到错误的窗口,崩溃,如果你有function或macros定义不正确,或者只是不工作,因为东西没有正确的连接。 更难debugging,更容易打破,不知不觉中。
  2. COM /自动化:与消息映射类似,COM最初是使用macros运行时绑定的,需要大量的error handling并导致奇怪的问题。 ATL使它基于模板,编译时间限制,而且更容易处理。

[编辑点缀:在创buildATL时,微软的技术路线图主要集中在'文档pipe理'上。 苹果公司正在桌面出版业中杀害他们。 办公室的“文件链接和embedded”是增强办公室“文件pipe理”function在这个领域竞争的一个主要组成部分。 COM是应用程序集成发明的核心技术,而Document Embedding API是基于COM的。 MFC很难用于这个用例。 ATL是使第三方实现COM和利用文档embeddedfunction更容易的特殊技术的一个很好的解决scheme。]

这些小的改进使得ATL在一个简单的应用程序上非常容易处理,它不需要像MFC那样的所有办公室。 用一个简单的用户界面和一些Office自动化引发的东西。它很小,速度快,编译时间为您节省了大量的时间和头痛。 MFC有一个巨大的类库,可能笨重,很难合作。

不幸的是,ATL停滞不前。 它有Windows API和COM支持的包装,然后它永远不会超越。 当networking起飞时,所有这些东西都被当作旧消息而被遗忘。

[编辑点缀:微软意识到这个'互联网事情'会变得很大。 他们的技术路线图发生了巨大变化,专注于分布式事务处理服务器中的Internet Explorer,Windows Server,IIS,ASP,SQL Server,COM / DCOM。 所以文档链接和embedded不再是高优先级。]

MFC的巨大脚印使它们不可能倾倒,所以它仍然缓慢地演变。 已将模板重新纳入库中,以及其他语言和API增强function。 (我没有听说过WTL,直到我看到这个问题。:)

最终,使用哪一个只是一个偏好问题。 您需要的大部分function都在基本OS API中,如果库中没有合适的包装器,您可以直接从两个库中调用该API。

基于使用MFC多年,我的2美分,我现在每天使用它。 在几年的时间里,我在一些项目上发布了ATL。 在那个时代,这是一股清新的气息,但从来没有去过任何地方。 然后networking出现,我忘记了一切。


编辑:这个答案有惊人的长寿。 由于它在我的堆栈溢出页面中一直popup,我想我会添加一些点缀,我认为是缺乏的原始答案。

很多人都告诉我,使用ATL的编程经验比使用MFC要less。 用ATL编译的可执行文件也会小得多。

我build议你看看WTL ,因为它build立在ATL之上。

他们不断提及的“额外function”是什么? 我需要它吗?

如果您定义您的要求,如果您可以避免使用MFC,则可能会更容易回答。 不幸的是,“没有什么特别的”并不足够。 包含你打算使用哪些function可能会更有帮助(控制哪个框架/技术/现有的库,等等)。

但是这里有一篇文章介绍了MFC中不直接被WTL / ATL支持的一些function。

MFC也已经发展到支持许多理想的function,如MAPI,支持其他Windows徽标要求,套接字,文档(如果您喜欢和/或使用该模式)以及复合文档文件。 WTL有它很酷的function,但MFC是清晰的function冠军。 这两种环境都支持框架化的主窗口体系结构(具有独立视图窗口的框架窗口),SDI和MDI应用程序,拆分窗口,基于对话框的应用程序以及用于COM支持的各种基于COM的类。

ATL是一组旨在简化COM对象实现的类。

你可以使用它没有MFC。 在我的工作中,我们使用ATL将COM接口暴露给计算代码。 没有涉及的GUI,这是我们能够从例如调用这个计算代码。 Excel VBA。

看一些COM指南/教程,看看它的摘要。

MFC只是一组到Win32 API的GUI包装类。 看看一些Win32 API教程,看看它的摘要。