【问题标题】:What's the fundamental difference between MFC and ATL?MFC和ATL之间的根本区别是什么?
【发布时间】:2011-11-04 22:31:08
【问题描述】:

假设我将它们用于“普通”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,但我不知道为什么。

      • 究竟 ATL 不提供的 MFC 的“内置功能”是什么?

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

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

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

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

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

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

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

我在这里错过了什么?

【问题讨论】:

  • 我可能是错的,但我知道 MFC 需要一个相当庞大的运行时 DLL,而我认为 ATL 将所有内容构建到一个 exe 中。 ATL 通常重量较轻。另外,check out WTL
  • @Merlyn:是的,但是为什么它需要一个庞大的运行时 DLL?造成这种情况的根本区别是什么?
  • 继承从 DLL 链接的预编译类与继承通过源代码包含/模板实例化链接的模板之间的区别相同。模板通常是“仅标头”库。我的回答是不完整的,因此在 cmets 中 :) 由于大量采用和向后兼容性,MFC 仍然存在。否则,MS 在创建更新的 win32 包装器时会将其丢弃。他们的软件往往有很长的支持合同(各不相同,但最长 10 年)。支持与弃用并不矛盾。
  • @Merlyn:所以我的理解是我不应该使用 MFC?他们一直提到的“额外功能”是什么?我需要它吗?
  • @Merlyn:听说过 ATL.DLL?听说过“使用 MFC 作为静态库”这个术语吗?

标签: c++ visual-c++ mfc atl


【解决方案1】:

如果您回顾一下这两个库是如何起源和演变的,我认为您的问题的答案主要是历史性的。

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

长答案: MFC 是在 90 年代初构建的,旨在尝试这种称为 C++ 的新语言并将其应用于 Windows。当操作系统还没有类似 Office 的功能时,它使开发社区可以使用这些功能。

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

当时这个库非常原始,因为 C++ 语言和编译器都是新的,而且微软随着 Office 的发展逐渐构建它。

由于这段历史,MFC:

  1. 有一个相当笨重的设计。它最初是作为 Windows API 的轻量级包装器,但后来发展壮大。由于编译器和语言不支持它们,因此必须发明许多小“功能”。没有模板,他们发明了一个字符串类,他们发明了列表类,他们设计了自己的运行时类型标识,等等。
  2. 封装了 Office 和 Windows 20 年的发展历程,其中包括一大堆您可能永远不会使用的东西:单文档和多文档界面、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 时,微软的技术路线图主要集中在“文档管理”上。苹果在桌面出版业务中扼杀了他们。 Office“文档链接和嵌入”是增强 Office 的“文档管理”功能以在该领域竞争的主要组件。 COM 是为应用程序集成而发明的核心技术,而 Document Embedding API 是基于 COM 的。 MFC 很难用于这个用例。 ATL 是一个很好的解决方案,可以让第三方更轻松地实施 COM 和利用文档嵌入功能。]

这些小改进使 ATL 在不需要 MFC 的所有 Office 功能的简单应用程序上更容易处理。带有简单 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 在几个项目中首次发布时,我涉足了几年。在那些日子里,这是一股新鲜空气,但从未真正去任何地方。然后网络出现了,我忘记了一切。


编辑:这个答案具有惊人的寿命。由于它不断在我的堆栈溢出页面中弹出,我想我会在我认为缺少的原始答案中添加一些修饰。

【讨论】:

  • 只是想提一下...我用了几天的MFC,然后切换到我已经使用了一段时间的ATL/WTL。它太棒了。可能再也不会看 MFC 了。
  • 那么微软是使用两者来构建新程序,还是决定使用其中一个而不是另一个?
【解决方案2】:

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

我推荐你take a look at WTL,因为它建立在 ATL 之上。

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

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

但这里是an article that describes some features in MFC that aren't directly supported by WTL/ATL.

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

【讨论】:

  • Jay 的回答有这个节拍。留下这篇文章的链接,解释一些差异。
【解决方案3】:

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

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

查看一些 COM 指南/教程以了解其中的抽象内容。

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

【讨论】:

  • ATL 也可以在不涉及任何 COM 的情况下使用。其中的许多类与 COM 无关,这在查看 WTL 时会更加明显。
  • @0xC0000022L:当我写这篇文章时,我并不知道CWindowImpl 和朋友们。现在我对 ATL 有了更多的经验,我可以尝试重写这个答案。特别是 ATL/WTL 几乎可以替代所有的 MFC。
猜你喜欢
  • 2014-09-04
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 2017-01-17
  • 2011-11-21
  • 2011-12-10
  • 2017-04-15
  • 2013-08-26
相关资源
最近更新 更多