MFC和ATL有什么根本区别?

119

假设我只使用它们来开发“普通”GUI程序(不使用COM,没有ActiveX,没有高级功能),ATL和MFC之间的基本区别是什么,以帮助我确定应该使用哪一个?


我在网上进行了一些搜索,但最终没有一个答案真正回答了我的问题:

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

    • "ATL是使用C++创建COM组件并保持小占用空间的快速简便方法。如果你不需要MFC自动提供的所有内置功能,请使用ATL创建控件。"

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

      • 我不使用COM。

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

    • "MFC允许你创建完整的应用程序、ActiveX控件和活动文档。如果你已经使用MFC创建了控件,可能希望继续使用MFC进行开发。在创建新控件时,如果你不需要MFC的所有内置功能,请考虑使用ATL。"

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

      • 我甚至不知道什么是ActiveX。

      • 看起来微软正在鼓励使用ATL,但我无法弄清楚为什么。

      • MFC的“内置功能”到底是什么,ATL没有提供?

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

因为直接或间接地,一切似乎都与前一页有关:

根据我最近观察到的(在过去几天里,尝试学习两者的过程中):

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

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

  • 两者都使用消息映射(BEGIN_MSG_MAP vs. BEGIN_MESSAGE_MAP...有什么大不了的)
  • 两者都将Win32方法封装成类
  • 两者似乎有类似的类 CWnd vs. CWindow

然而,如果除了编译时与运行时这个方面没有实际区别,那么为什么两者都存在呢?难道不应该只需要一个吗?

我在这里错过了什么吗?


3
我可能错了,但我知道MFC需要一个相当庞大的运行时DLL,而ATL则将所有内容都构建到一个exe文件中。总的来说,ATL更轻量级。另外,请查看WTL(http://wtl.sourceforge.net/)。 - Merlyn Morgan-Graham
1
@Merlyn:没错,但是为什么它需要一个庞大的运行时DLL呢?是什么根本上的区别导致了这一点? - user541686
1
继承从DLL链接的预编译类和从源代码包含/模板实例化链接的模板之间的差异相同。 模板通常是“仅头文件”库。 我的答案不完整,因此在注释中 :) 由于巨大的采用率和向后兼容性,MFC仍然存在。 否则,当他们创建更新的win32包装器时,MS会将其丢弃。 他们倾向于在其软件上拥有长期支持合同(变化,但长达10年)。 支持与弃用不兼容。 - Merlyn Morgan-Graham
2
@Merlyn:听说过ATL.DLL吗?听说过“将MFC用作静态库”的术语吗? - Ajay
虽然我不使用ATL,但在项目属性中有一个设置:“使用ATL:动态链接到ATL”,并且有ATL.DLL / ATL100.DLL。 其中一个导出函数是:AtlModuleInit - Ajay
显示剩余3条评论
3个回答

191
我认为你问题的答案主要是历史性的,如果你回顾一下这两个库是如何起源并随时间演变的。
简短的答案是,如果你没有进行任何“高级”的操作,请使用ATL。它非常适合带有COM的简单用户界面。
长答案: MFC是在90年代初建立的,用于尝试这种名为C++的新语言,并将其应用于Windows。当操作系统还没有这些功能时,它使Office类似的功能可供开发社区使用。
[编辑装饰:我没有在微软工作,所以不知道Office是否曾经建立在MFC上,但我认为答案是否定的。在Win 3.1、Win 95时代,Office UI团队会发明新的控件,将它们打包成库,然后Windows和MFC团队会通过可重新分发的dll包装器和API将这些控件整合到一起。我想这些团队之间有一些协作和代码共享。最终,这些控件会在服务包或下一个Windows版本中成为基础操作系统的一部分。办公室缘带被添加到Windows作为插件组件,其后才成为Windows操作系统的一部分。]
那时,该库相当原始,既因为C++语言和编译器是新的,又因为Microsoft随着Office的演变而逐步建立了它。
由于这个历史,MFC:
  1. 设计相对臃肿。它最初只是Windows API的一个轻量级包装器,但逐渐壮大。由于编译器和语言本身不支持一些小的“功能”,所以必须发明一些东西。例如没有模板,他们发明了字符串类、列表类,设计了自己的运行时类型识别等。
  2. 封装了20年的Office和Windows演变,其中包括许多你可能永远不会使用的东西:单文档和多文档接口、DDE、COM、COM+、DCOM、文档链接和嵌入(这样你就可以将Word文档嵌入到你的应用程序中),ActiveX控件(Web对象嵌入的演变!)、结构化文档存储、序列化和版本控制、自动化(来自早期的VBA年代)以及MVC。最新版本支持Visual Studio风格的窗口停靠和Office功能区。基本上,20年里Redmond的所有技术都在其中。简直太庞大了!
  3. 有很多小问题、错误、解决方法、假设、支持那些你永远不会使用的东西,它们会引起问题。你需要非常熟悉许多类的实现方式以及它们之间的交互才能在一个相当大的项目中使用它。在调试过程中深入MFC源代码是很常见的。仍然会出现找到15年前某个指针为空导致崩溃的技术注释。对古老文档嵌入的初始化假设可能以奇怪的方式影响你的应用程序。在MFC中不存在抽象,你需要每天处理它的怪癖和内部机制,它不会隐藏任何东西。而且别让我再谈类向导了。

随着C++语言的发展和模板的引入,ATL被发明出来了。 ATL展示了如何使用模板避免MFC库的运行时问题:

  1. 消息映射:由于它们是基于模板的,类型是经过检查的,如果绑定函数出错,它就不会构建。在MFC中,消息映射是基于宏的,并且是运行时绑定的。这可能会导致奇怪的错误,例如将消息路由到错误的窗口、如果你定义的函数或宏不正确则崩溃,或者只是因为某些东西没有正确连接而无法工作。更难调试,更容易不注意就破坏了。
  2. COM/自动化:与消息映射类似,最初使用宏进行运行时绑定,需要大量的错误处理,会导致奇怪的问题。ATL使其基于模板、编译时绑定,并且更加容易处理。
在ATL创建时,微软的技术路线主要集中在“文档管理”上。苹果在桌面出版业务方面表现出色,而Office的“文档链接和嵌入”是提高Office“文档管理”功能以在该领域竞争的主要组成部分。COM是为应用程序集成发明的核心技术,文档嵌入API基于COM。MFC对于此用例来说很难使用。ATL是使第三方实现COM并利用文档嵌入功能更容易的好解决方案。
这些小改进使ATL在简单应用程序上处理起来非常容易,这些应用程序不需要MFC的所有Office样式功能。一些简单的UI和一些Office自动化。它很小,很快,编译时间绑定可以节省您很多时间和头痛。MFC有一个庞大的类库,可能会很笨拙且难以使用。
不幸的是,ATL停滞了。它具有Windows API和COM支持的包装器,然后就没有超越这一点。当Web开始流行时,所有这些东西都被遗忘了。
微软意识到这个“互联网事物”将会变得很大,他们的技术路线发生了巨大变化,专注于Internet Explorer,Windows Server,IIS,ASP,SQL Server,COM / DCOM在分布式事务服务器中。因此,文档链接和嵌入不再是高优先级。
MFC的巨大占用空间使它们无法丢弃,因此它仍然缓慢发展。模板已经并入库中,以及其他语言和API增强功能。(在看到这个问题之前,我从未听说过WTL。:)
最终,使用哪个库只是个人偏好问题。您所需的大多数功能都在基本操作系统API中,如果库中没有适当的包装器,则可以直接从任一库中调用。
根据我多年使用MFC的经验(我现在每天都在使用),我认为这只是我的2美分。ATL发布时,我曾在几个项目中涉足过ATL,并且在那些日子里它是一股清新的空气,但从来没有真正走得很远。然后Web出现了,我忘记了所有这些。

3
只想提一下... 我用 MFC 用了几天,然后转到 ATL/WTL,现在已经使用它有一段时间了。它真的很棒。也许再也不会看 MFC 了。 - user541686
1
微软是同时使用这两种编程语言来构建新程序,还是已经决定使用其中一种? - The Muffin Man
@TheMuffinMan 我知道这可能晚了好几年,但我不认为他们使用任何一种。旧版 Office 应用程序总是在做他们自己的事情。有段时间它全都围绕 .NET 库展开。现在我并不清楚,你最近还看到过微软出品的新软件吗? - Mark Ransom

24

很多人告诉我,他们使用ATL时编程体验比使用MFC更轻松。使用ATL编译出的可执行文件也会更小。

我建议你看看WTL,因为它是在ATL基础上构建的。

他们一直提到的“额外功能”是什么?我需要它吗?

如果您定义了您的需求,那么回答是否可以避免使用MFC会更容易。不幸的是,“没有花哨的东西”并不足够具体。列举您想要使用的特定组件、框架/技术/现有库(例如控件、框架、技术等)可能更有帮助。

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

MFC还发展到支持许多理想的功能,例如MAPI、支持其他Windows徽标要求、套接字、文档(如果您喜欢和/或使用该模式)和复合文档文件。WTL也有许多酷炫的功能,但MFC是明显的功能冠军。两个环境都支持带框架的主窗口体系结构(具有单独的视图窗口的框架窗口),SDI和MDI应用程序,分割窗口,基于COM的各种类以支持COM。


5
杰伊的回答更优秀。留下此链接以解释其中一些差异。 - Merlyn Morgan-Graham

11

ATL是一组用于简化COM对象实现的类。

您可以在没有MFC的情况下使用它。在我的工作中,我们使用ATL来向计算代码公开COM接口。没有涉及GUI,我们可以从Excel VBA等程序中调用此计算代码。

查看一些COM指南/教程,以了解它所抽象的内容。

MFC只是Win32 API的GUI包装器类集。查看一些Win32 API教程,以了解它所抽象的内容。


ATL也可以在没有任何COM参与的情况下使用。其中许多类与COM无关,当看到WTL时这一点变得更加明显。 - 0xC0000022L
1
@0xC0000022L:在我编写这个答案时,我不知道CWindowImpl和相关内容。现在我对ATL有了更多的经验,我可以尝试重写这个答案。特别是,ATL/WTL几乎可以替代所有MFC。 - Alexandre C.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接