【问题标题】:Why STL containers are preferred over MFC containers?为什么 STL 容器优于 MFC 容器?
【发布时间】:2010-11-23 19:13:26
【问题描述】:

以前,我曾经使用过CArrayCMap 等MFC 集合类。一段时间后,我切换到 STL 容器并使用了一段时间。虽然我发现 STL 好多了,但我无法指出它的确切原因。一些推理如:

  1. 它需要 MFC:不成立,因为我的程序的其他部分使用 MFC
  2. 它取决于平台:不成立,因为我只在 Windows 上运行我的应用程序。(不需要可移植性)
  3. 在 C++ 标准中定义:好的,但 MFC 容器仍然可以工作

我能想到的唯一原因是我可以在容器上使用算法。还有什么我在这里遗漏的其他原因 - 是什么让 STL 容器比 MFC 容器更好

【问题讨论】:

  • 您可能想在此问题的标题中添加不关心可移植性的问题。目前,仅标题并不能满足您的某些要求。
  • STL 肯定更好,因为所有答案都表明,但真正让我感到震惊的是,仍然有使用 MFC 容器进行写作的人。诚然,他们主要使用模板容器,但必须在两者之间移动是浪费。为什么 MS 既不弃用它们也不向它们添加迭代器只是它们坐在栅栏上惹恼了其他所有人。
  • @Adrian 因为我们中的一些人必须使用遗留代码,但需要最新的工具。既支持旧的东西,又鼓励新的东西是两全其美的。相信我,如果 MS 确实移除了旧容器,我会更加满意。考虑一个事实,如果您使用的是 MFC,那么您可能首先处理的是“遗留”-ish 应用程序。 :-D
  • @franji1,如果你看看我读到的内容,我也说过:or add iterators to them。我理解为什么它没有被删除,但是 ppl 应该停止用他们实现新的东西。将迭代器添加到这些容器中也不会花费 MS 太多,以帮助那些使用遗留东西的人以最小的风险编写更好的代码。另外,请在我的上一篇文章中将 is just 替换为 instead of,我必须输入它在我的手机上并自动更正。

标签: c++ mfc stl containers


【解决方案1】:

Ronald Laeremans,VC++ 产品部门经理,2006 年 6 月甚至 said to use STL

坦率地说,团队会给你同样的答案。 MFC 集合类仅用于向后兼容。 C++ 有一个集合类的标准,那就是标准 C++ 库。在 MFC 应用程序中使用任何标准库都没有技术缺陷。

我们不打算在这方面做出重大改变。

Ronald Laeremans
代理产品部门经理
Visual C++ 团队

但是,有一次我正在编写一些在 Windows 安装阶段运行的代码,但不允许我使用 STL 容器,而是被告知要使用 ATL 容器(实际上是 CString,尤其是我想这不是一个真正的容器)。解释是 STL 容器依赖于运行时位,这些位在代码必须执行时可能实际上不可用,而 ATL 集合不存在这些问题。这是一个相当特殊的场景,不应该影响 99% 的代码。

【讨论】:

  • CString 并不是真正的容器(除非在非常技术意义上),它确实有很多方便的功能,使其更适合在处理 Win32 和 COM API 时使用很多。
  • “解释是 STL 容器依赖于运行时位,这些位在代码必须执行时可能实际上不可用” ...现在我会喜欢在 STL 中查看 container 代码的 that 部分。当然,我不确定是否所有这些调试检查都是可选的,但对于一个简单的发布版本,我会说所有 STL 集合都是纯标头,不涉及运行时位。 (快速检查 C++STDLIB MSVCP*.DLL 也没有发现任何与容器相关的导出。)
  • @MartinBa:我推测这很微妙:可能在 std::allocator<X>::allocate 的实现方式、异常类等细节中。
  • 我怀疑MS当时使用的C++编译器是否有足够的能力支持STL。
【解决方案2】:

STL 容器:

  • 有性能保证
  • 可用于 STL 算法也有性能保证
  • 可由第三方 C++ 库(如 Boost)利用
  • 是标准的,并且可能比专有解决方案寿命更长
  • 鼓励对算法和数据结构进行通用编程。如果您编写符合 STL 的新算法和数据结构,则可以免费利用 STL 已经提供的功能。

【讨论】:

    【解决方案3】:
    • 在语法、互操作性和范式方面与其他库(如 boost)的兼容性。这是一个不平凡的好处。
    • 使用 STL 将培养一种更有可能在其他情况下有用的技能。 MFC 不再被广泛使用。 STL 是。
    • 使用 STL 会培养一种思维方式,您可能会(或可能不会)发现在自己编写的代码中有用。

    不过,使用 STL 以外的东西本身并没有错。

    【讨论】:

      【解决方案4】:
      • STL 的集合类型比 MFC 多
      • Visual Studio (2008+) 调试器对 STL 的可视化效果比 MFC 好得多。(AUTOEXP.DAT 魔法可以解决这个问题 - 但这很痛苦!当你搞砸了调试器时,没有什么比调试它更好了...)

      MFC 的一个好处是仍然有大量的 MFC 代码。其他答案谈论第三方兼容性。不要忘记第三方基于 MFC 的东西。

      【讨论】:

      • 是的,就 STL 而言,我只是喜欢 VS2008 调试器。以前我使用的是 VC6,而转换到 VS2008 让我的生活变得轻松多了。
      • 我最近在 autoexp.dat 中发布了一个补充内容:thetweaker.wordpress.com/2010/01/11/…
      【解决方案5】:

      我总是更喜欢尽可能使用更多标准/兼容的库,因为我可能有未来的项目可以重用部分代码。我不知道未来的项目将使用哪些库,但如果我使用标准/兼容的东西,我就有更好的机会使我的代码可重用。

      此外,我使用图书馆的次数越多,我就越会感到舒适和快速。如果我要花时间学习一个库,我想确保它能够一直存在并且不与特定的平台或框架绑定。

      当然,我说所有这些都是假设我的选择在性能、功能和易用性方面非常相似。例如,如果 MFC 类在这些领域有足够显着的改进,我会改用它们。

      【讨论】:

        【解决方案6】:

        事实上you can use STL algorithms on some of MFC containers as well。然而,首选 STL 容器还有一个非常实际的原因:许多第三方库(Boost、arabica、Crypto++、utf-cpp...)旨在与 STL 一起使用,但对 MFC 容器一无所知。

        【讨论】:

          【解决方案7】:

          MFC 容器派生自 CObjectCObject 已将赋值运算符设为私有。在实践中我发现这很烦人。

          std::vectorunlinke CArray,保证内存块是连续的,因此可以轻松与C编程接口互操作:

          std::vector<char> buffer; 
          char* c_buffer = &*buffer.begin();
          

          【讨论】:

          【解决方案8】:

          现在假设 C++ 开发人员至少对 STL 非常熟悉。 MFC 容器并非如此。因此,如果您要向团队中添加新的开发人员,您将更容易找到了解 STL 的人而不是 MFC 容器,从而能够立即做出贡献。

          【讨论】:

            【解决方案9】:

            我认为这可以归结为一个简单的问题:您更信任谁?如果您信任 Microsoft,则继续使用 MFC 变体。如果您信任该行业,请使用 STL。

            我投票支持 STL,因为今天在 Windows 上运行的代码明天可能需要移植到另一个平台。 :)

            【讨论】:

            • 一般来说这是一个有效的观点,但在这个特殊情况下不是这样:无论如何,他到处都在使用 MFC,用 STL 替换 MFC 容器对他的应用程序的可移植性贡献很小。跨度>
            • 微软在他们自己的编译器上负责 MFC 和 STL,所以这是一个非参数。我从来没有发现这两种范式的可靠性不同。
            • 好点。不过,您始终可以使用第三方库。
            • 我唯一的评论是:MFC 在微软实际上不是一条死胡同吗?我似乎记得 2 年前(当我上次为 PC 编程时)不建议将 MFC 用于新开发。
            • @MichaelKohne 这里是 2018 年的 Visual Studio 2017,它仍然在 Visual Studio 产品中。 MFC 的问题在于界面看起来确实过时了,而且它确实需要 Win32 API 以及 MFC DLL。另一方面,相同的 MFC 应用程序可以在 Windows 10 上一直运行到 Windows XP,并且源代码可以使用 Visual Studio 6.x 编译到 Visual Studio 2017。
            【解决方案10】:

            这是一种适用于您想做的工作的工具的情况,“更好”是一个主观术语。

            如果您需要将容器与其他符合标准的代码一起使用,或者如果它要成为跨平台共享的代码,那么 STL 容器可能是更好的选择。

            如果您确定您的代码将保留在 MFC 中,并且 MFC 容器为您工作,为什么不继续使用它们?

            STL 容器在本质上并不比 MFC 容器更好,但是由于它们是标准的一部分,因此它们在更广泛的环境中更有用。

            【讨论】:

            • 在我的运营商中,我不止一次听到“这永远不会被移植”并且看到这种说法变得非常错误。
            【解决方案11】:

            在提到的方面:良好支持、标准可用、性能优化、设计用于算法,我可能会再添加一个方面:类型安全和大量编译时检查。你甚至无法想象从std::set&lt;int&gt; 中画出double

            【讨论】:

              【解决方案12】:

              因为一个库使用迭代器将任何类型的序列与算法相结合,因此 A)所有合理的排列都是可能的,并且 B)它是普遍可扩展的,是(当您考虑容器库的概念时,因为它是 15 年以前)如此令人兴奋的奇妙想法,在不到十年的时间里,它几乎把其他所有东西都从水中吹走了?

              说真的,STL 有其缺陷(为什么不使用范围而不是迭代器?而且擦除删除习惯并不完全漂亮),但它基于一个绝妙的想法,并且有很好的理由我们不需要学习每次我们开始新工作时都会有新的容器/算法库。

              【讨论】:

                【解决方案13】:

                我不会完全否定可移植性的论点。仅仅因为您今天使用 MFC 并不意味着您将永远如此。即使您主要为 MFC 编写代码,如果代码更通用且基于标准,您的某些代码也可以在其他应用程序中重用。

                我认为考虑 STL 的另一个原因是它的设计和演变得益于以前出现的库,包括 MFC 和 ATL。许多解决方案更清洁、更可重用且不易出错。 (虽然我希望他们有更好的命名约定。)

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2011-12-25
                  • 2013-07-21
                  • 1970-01-01
                  • 2011-07-24
                  • 2022-01-14
                  相关资源
                  最近更新 更多