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

Meh*_*dad 106 c++ mfc atl visual-c++

假设我使用它们用于"普通"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中进行开发.在创建新控件时,如果您不需要,请考虑使用ATL所有MFC的内置功能."

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

      • 我甚至不知道ActiveX 什么.

      • 看起来微软似乎不鼓励使用MFC,但我无法弄清楚原因.

      • MFC的"内置功能" 到底什么ATL没有提供?

    • 一般来说,这不能回答我的问题,因为它没有解释它们背后的缺点和原因.

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

目前观察到的(在过去几天内,在尝试学习两者时):

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

但它们之间似乎没有任何架构差异:

  • 两者都使用消息映射(BEGIN_MSG_MAPBEGIN_MESSAGE_MAP...大不了)
  • 两者都将Win32方法包装到类中
  • 两者似乎都有相似的类别CWndvs.CWindow

但是,如果除了编译时与运行时方面之外没有真正的区别,那么为什么它们都存在呢?其中一个不应该足够吗?

我在这里错过了什么?

Jay*_*Jay 168

我认为你的问题的答案主要是历史性的,如果你回顾一下这两个图书馆是如何产生和发展的.

简短的回答是,如果你没有做任何"花哨"的事情,请使用ATL.它非常适合投入COM的简单用户界面.

答案很长:MFC建于90年代初,试用这种名为C++的新语言并将其应用于Windows.当操作系统还没有它时,它使开发社区可以使用Office功能.

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

当时这个库非常原始,因为C++语言和编译器都是新的,而且随着Office的发展,微软会随着时间的推移建立它.

由于这段历史,MFC:

  1. 有一个相当笨重的设计.它起初是围绕Windows API的轻量级包装,但已经增长.由于编译器和语言不支持它们,因此必须发明一些小"特征".没有模板,他们发明了一个字符串类,他们发明了列表类,他们设计了自己的运行时类型标识等.
  2. 封装了20年的Office和Windows演变,其中包括您可能永远不会使用的全部垃圾:单个和多个文档界面,DDE,COM,COM +,DCOM,文档链接和嵌入(因此您可以嵌入word文档您的应用程序,如果您愿意),ActiveX控件(Web的对象嵌入的演变!),结构化文档存储,序列化和版本控制,自动化(从早期的VBA年代),当然还有MVC.最新版本支持Visual Studio样式窗口对接和Office功能区.基本上20年来雷德蒙德的每一项技术都在某处.这真是太棒了!
  3. 有大量的小问题,错误,变通方法,假设,支持仍然存在的东西,你永远不会使用,并且它们会导致问题.您需要非常熟悉许多类的实现以及它们如何交互以在适当大小的项目上使用它.在调试期间深入研究MFC源代码很常见.找到一个15年前的技术说明,一些指针为空,导致崩溃仍然发生.关于古代文档嵌入内容初始化的假设可能会以奇怪的方式影响您的应用程序.在MFC中没有抽象这样的东西,你需要每天使用它的怪癖和内部,它不会隐藏任何东西.并且不要让我开始上课向导.

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

  1. 消息映射:因为它们是基于模板的,所以检查类型,如果搞砸了绑定函数,它就不会构建.在MFC中,消息映射是基于宏的,并且是运行时绑定的.这可能会导致奇怪的错误,消息路由到错误的窗口,如果您的功能或宏定义不正确,则崩溃,或者只是因为没有正确连接的东西而无法工作.更难以调试,更容易在没有注意的情况下破解.
  2. COM/Automation:与消息映射类似,COM最初使用宏进行运行时绑定,需要大量错误处理并导致奇怪的问题.ATL使它基于模板,编译时间限制,并且更容易处理.

[编辑点缀:在ATL创建时,微软的技术路线图主要集中在'文档管理'.Apple在桌面出版业务中杀死了他们.Office"文档链接和嵌入"是增强Office的"文档管理"功能以在此领域竞争的主要组成部分.COM是为应用程序集成而发明的核心技术,Document Embedding API基于COM.MFC很难用于这个用例.ATL是一个很好的解决方案,使第三方能够更轻松地实现COM并利用文档嵌入功能.

这些小小的改进使得ATL在一个简单的应用程序上更容易处理,这个应用程序不需要MFC的所有办公室功能.有一些简单的UI和一些Office自动化的东西.它很小,很快,它的编译时间限制,节省了你很多时间和头痛.MFC有一个庞大的类库,可能很笨重,而且难以使用.

不幸的是,ATL停滞不前.它有Windows API和COM支持的包装器,然后它从未真正超越它.当网络起飞时,所有这些东西都被遗忘为旧消息.

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

MFC的巨大足迹使它们无法倾倒,因此它仍然发展缓慢.模板已合并到库中,以及其他语言和API增强功能.(在我看到这个问题之前,我没有听说过WTL.:)

最终,使用哪一个只是一个偏好问题.您需要的大多数功能都在基本OS API中,如果库中没有合适的包装器,您可以直接从任一库调用它们.

仅仅基于使用MFC多年的2美分,我现在每天都使用它.我在几年的几个项目中首次发布时涉足ATL.在那些日子里,这是一股清新的空气,但从未真正去过任何地方.然后网络出现了,我忘记了它.


编辑:这个答案令人惊讶的长寿.由于它不断出现在我的堆栈溢出页面中,我想我会在我认为缺乏的原始答案中添加一些点缀.

  • +1我希望我能+10这个.感谢您出色的历史描述 - 它写得非常好,信息丰富!:) (37认同)
  • 只是想提一下...我使用了MFC几天,然后切换到ATL / WTL,这已经有一段时间了。而且真是太棒了。也许再也不会看MFC了。 (3认同)

Mer*_*ham 19

很多人都告诉我,他们的编程经验对ATL的痛苦比对MFC的痛苦少.使用ATL,您编译的可执行文件也会小得多.

我建议你看看WTL,因为它建立在ATL之上.

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

如果您定义了要求,如果可以避免使用MFC,则可能更容易回答.不幸的是,"没什么特别的"不够独占.包含您打算使用哪些功能可能更有帮助(哪些控件,您想要使用哪些框架/技术/现有库等).

这篇文章描述了MFC中WTL/ATL不直接支持的一些功能.

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

  • 杰伊的答案有这个节拍.留下这个链接到文章解释一些差异. (3认同)

Ale*_* C. 9

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

您可以在没有MFC的情况下使用它.在我的工作中,我们使用ATL将COM接口暴露给计算代码.没有涉及GUI,我们能够从例如调用此计算代码.Excel VBA.

查看一些COM指南/教程,了解它的摘要.

MFC只是Win32 API的一组GUI包装类.查看一些Win32 API教程,了解它的摘要.