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


110

假设我将它们用于“常规” GUI程序(没有COM,没有ActiveX,没什么花哨的东西),那么我将在ATL和MFC之间看到什么根本的区别,以帮助我确定要使用哪一个?


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

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

    • “ ATL是一种快速,简便的方法,既可以用C ++创建COM组件,又可以保持较小的占用空间。如果不需要MFC自动提供的所有内置功能,则可以使用ATL创建控件。”

      并未真正回答我的问题,因为:

      • 我不在使用COM。

      • 这是否意味着MFC 是不是快吗?为什么/如何?

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

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

      • 我什至不知道ActiveX 首先什么。

      • 微软似乎不鼓励使用MFC,但我不知道为什么。

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

    • 总的来说,这不能回答我的问题,因为它不能解释不利因素及其背后的原因。

因为直接或间接,所有内容似乎都链接回到上一页:

目前观察到的(在最近几天内,试图同时学习两者):

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

它们之间似乎在架构上没有任何区别

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

但是然后,如果除了编译时和运行时方面没有真正的区别,那么为什么两者都存在?其中之一不够吗?

我在这里想念什么?


3
我可能是错的,但是我知道MFC需要一个较大的运行时DLL,而我认为ATL将所有内容都构建到一个exe中。一般而言,ATL的重量较轻。另外,请查看WTL
Merlyn Morgan-Graham

@Merlyn:是的,但是为什么它需要一个庞大的运行时DLL?造成这种情况的根本区别是什么?
2011年

1
继承从DLL链接的预编译类和继承通过源代码包含/模板实例化链接的模板之间的相同区别。模板通常是“仅标头”的库。我的答案是不完整的,因此在注释中:)由于采用率高和向后兼容,MFC仍然存在。否则,MS在创建更新的Win32包装程序时会把它扔掉。他们的软件往往具有长期的支持合同(不同,但最长为10年)。支持与弃用不兼容。
Merlyn Morgan-Graham

@梅林:所以我的理解是我不应该使用MFC?他们不断提到的“额外功能”是什么?我需要吗?
2011年

2
@Merlyn:听说过ATL.DLL吗?听说过术语“使用MFC作为静态库”吗?
阿贾伊(Ajay)

Answers:


179

如果您回顾一下这两个库是如何随着时间而产生和演变的,我认为您的问题的答案大部分是历史性的。

简短的答案是,如果您没有做任何“花哨的事情”,请使用ATL。非常适合带有COM的简单用户界面。

长话大说:MFC始建于90年代初,尝试使用这种称为C ++的新语言并将其应用于Windows。当OS尚不具备Office类功能时,它便可供开发社区使用。

[编辑点缀:我没有在Microsoft工作,所以我不知道Office是否曾经建立在MFC上,但是我认为答案是否定的。回到Win 3.1,即Win 95,Office UI团队将发明新的控件,并将其打包在库中,然后Windows和MFC团队将包装和API合并到具有可再发行dll的那些控件中。我猜想这些团队之间会有一些协作和代码共享。最终,这些控件会将其放入Service Pack或下一Windows版本的基本操作系统中。Office Ribbon在Office出厂后作为附加组件添加到Office Ribbon中继续了这种模式,现在它已成为Windows OS的一部分。]

当时,该库非常原始,这是因为C ++语言和编译器是新的,并且随着Office的发展,Microsoft随着时间的推移逐步建立了该库。

由于这个历史,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中没有诸如抽象之类的东西,您需要每天使用它的怪癖和内部知识,它不会隐藏任何东西。而且不要让我开始上课向导。

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

  1. 消息映射:由于它们是基于模板的,因此将检查类型,如果您破坏绑定函数,则不会生成。在MFC中,消息映射是基于宏的,并且是运行时绑定的。如果您错误地定义了函数或宏,这可能会导致奇怪的错误,错误的消息发送到错误的窗口,崩溃,或者只是由于某些错误而无法正常工作而导致崩溃。调试起来更加困难,并且在不注意的情况下更容易破坏。
  2. COM /自动化:类似于消息映射,COM最初是使用宏在运行时绑定的,需要处理大量错误并引起奇怪的问题。ATL使它成为基于模板的编译时限,并且非常容易处理。

[编辑点缀:在创建ATL时,Microsoft的技术路线图主要集中在“文档管理”上。苹果在台式机出版业务中杀死了他们。Office的“文档链接和嵌入”是增强Office的“文档管理”功能以在此领域竞争的主要组件。COM是为应用程序集成而发明的核心技术,而Document Embedding API是基于COM的。MFC很难用于此用例。ATL是使第三方更容易实现此特定技术并实现COM并利用文档嵌入功能的好解决方案。

这些小的改进使ATL在不需要MFC等所有办公功能的简单应用程序上非常容易处理。它具有简单的UI和一些Office自动化功能。它体积小,速度快,编译时长,可节省大量时间和头痛。MFC有一个庞大的类库,这些类很笨拙,并且很难使用。

不幸的是ATL停滞了。它具有Windows API和COM支持的包装器,然后再也没有超出它的范围。当网络腾飞时,所有这些东西都被当作旧新闻而遗忘了。

[编辑点缀:Microsoft意识到这种“互联网事物”将变得很大。他们的技术路线图发生了巨大变化,将重点放在了分布式事务服务器中的Internet Explorer,Windows Server,IIS,ASP,SQL Server,COM / DCOM上。因此,文档链接和嵌入不再是重中之重。]

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

归根结底,使用哪一个只是一个优先事项。您需要的大多数功能都在基本OS API中,如果该库中没有合适的包装器,则可以直接从这两个库中调用它们。

基于使用MFC多年,仅凭我的2美分,现在我每天都使用它。当ATL在几个项目中首次发布时,我涉足了两年。那时那是一口新鲜的空气,但从未真正消失过。然后网络出现了,我对此一无所知。


编辑:这个答案具有长寿。由于它一直在我的堆栈溢出页面中弹出,因此我想为原来认为缺少的原始答案添加一些修饰。


39
+1,我希望我可以+10。感谢您对历史的出色描述-编写得非常好并且内容翔实!:)
user541686 2011年

3
只是想提一下...我使用了MFC几天,然后切换到ATL / WTL,这已经有一段时间了。而且真是太棒了。也许再也不会看MFC了。
user541686

1
那么Microsoft是否要同时使用这两种程序来构建新程序,还是已决定使用其中一种?
松饼人

1
我以为我知道区别..但从未见过如此优美而精致的解释..竖起大拇指..谢谢你一吨:)
shivi 2015年

1
我读过的关于该主题的最佳答案;您应该撰写包括WTL在内的文章
Pat

20

许多使用过这两种方法的人告诉我,他们的编程经验对ATL的痛苦比对MFC的痛苦小。使用ATL,您编译的可执行文件也将小得多。

我建议您看一下WTL,它基于ATL。

他们不断提到的“额外功能”是什么?我需要吗?

如果定义了要求,则可以避免使用MFC,这可能会更容易回答。不幸的是,“花哨的东西”还不够排他。包容您打算使用哪些功能可能会更有帮助(要控制哪些控件,要使用哪些框架/技术/现有库等)。

但是,本文是介绍WTL / ATL不直接支持的MFC中的某些功能的文章。

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


3
周杰伦的答案胜出了。将其留给文章的链接,以解释其中的一些差异。
Merlyn Morgan-Graham

9

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

您可以在不使用MFC的情况下使用它。在我的工作中,我们使用ATL将COM接口公开给计算代码。不涉及GUI,对我们而言,它能够从例如调用此计算代码。Excel VBA。

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

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


也可以在不涉及任何COM的情况下使用ATL。它中的许多类与COM没有关系,而COM在查看WTL时会更加明显。
0xC0000022L 2014年

1
@ 0xC0000022L:CWindowImpl当我写这篇文章时,我并不认识和朋友。现在,我对ATL有了更多的经验,我可以尝试重写此答案。特别是,ATL / WTL实际上可以替代所有MFC。
Alexandre C.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.