STL容器为什么比MFC容器更受青睐?

31

之前,我使用MFC集合类,例如CArrayCMap。一段时间后,我切换到STL容器并使用它们一段时间了。尽管我发现STL要好得多,但我无法准确指出原因。如下是其中一些推理:

  1. 需要 MFC:不适用,因为我的程序的其他部分使用MFC。
  2. 平台相关:不适用,因为我只在Windows上运行应用程序(不需要可移植性)。
  3. 已在C++标准中定义:可以,但MFC容器仍然可用。

我唯一能想到的原因就是我可以在容器上使用算法。这里是否有我错过的其他原因 - 是什么使STL容器比MFC容器更好?


2
您可能需要在此问题的标题中添加可移植性不是一个问题的说明。仅凭标题无法完全捕捉您当前的一些要求。 - Will Bickford
1
STL 明显更好,正如所有答案所述,但真正让我恼火的是仍有人使用 MFC 容器进行编写。尽管他们大多数使用模板容器,但在两者之间切换是浪费的。微软为什么不将它们弃用或添加迭代器呢?这只是他们坐视不管惹怒其他人。 - Adrian
@Adrian 因为我们中的一些人必须使用遗留代码,但想要最新的工具。支持旧代码,同时鼓励新技术是两全其美的选择。相信我,如果微软删除了旧容器,我会更加恼火。请考虑这样一个事实,如果您正在使用MFC,则可能首先处理“遗留”应用程序。 :-D - franji1
@franji1,如果你看一下我之前的留言,我也提到了:“或者给它们添加迭代器”。我明白为什么不会移除它们,但人们应该停止使用它们来实现新功能。微软花费一些成本为这些容器添加迭代器,可以帮助那些使用旧代码的人以最小的风险编写更好的代码。另外,请在我的最后一条留言中将“is just”替换为“instead of”,我可能是在手机上输入时被自动更正了。 - Adrian
13个回答

47

Ronald Laeremans,VC++产品单位经理,甚至在2006年6月建议使用STL

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

我们不打算在这个领域进行重大改变。

Ronald Laeremans
代理产品单位经理
Visual C ++团队

然而,在我工作期间需要在Windows安装阶段运行的某些代码时,我被告知不能使用STL容器,而是要使用ATL容器(特别是CString,我想它并不是真正的容器)。解释是STL容器对运行时位有依赖,而这些依赖可能在代码执行时实际上并不可用,而ATL集合不存在这些问题。这是一个相当特殊的场景,不应影响99%的现有代码。


9
CString 并不是一个真正的容器(除非在很技术性的意义上),它有很多便利功能,使得在处理大量 Win32 和 COM API 时更加适用。 - Pavel Minaev
5
解释是STL容器有依赖于运行时的部分,这些部分在代码执行时可能并不可用。现在我想看看STL中与此相关的容器代码。考虑到所有可选的调试检查,在纯发布版本的情况下,我认为所有的STL集合都是纯头文件,并且没有涉及任何运行时的部分。(快速检查C++STDLIB MSVCP*.DLL也没有找到任何容器相关的导出项。) - Martin Ba
@MartinBa:我猜测这是微妙的问题:可能涉及到std::allocator<X>::allocate的实现细节、异常类以及其他相关内容。 - Mooing Duck
我怀疑当时微软使用的C++编译器是否足够支持STL。 - Johan Boulé

36

STL 容器:

  • 具有性能保证
  • 可以在 STL 算法中使用 这些算法也具有性能保证
  • 可以被第三方 C++ 库(例如 Boost)利用
  • 是标准的,可能会比专有解决方案更长久存在
  • 鼓励对算法和数据结构进行通用编程。如果您编写符合 STL 的新算法和数据结构,则可以免费利用 STL 已经提供的内容。

23
  • 与其他库(例如boost)在语法、互操作性和范式方面兼容。这是一个非微不足道的好处。
  • 使用STL可以培养一种技能,这种技能在其他环境中更有用。MFC已经不再被广泛使用;而STL却很常用。
  • 使用STL会培养出一种思维方式,你可能会在自己编写的代码中发现它(也可能不会)。

当然,使用STL以外的东西也并不是 inherently wrong (本质上错误的)。


8
  • STL拥有比MFC更多的集合类型
  • Visual Studio(2008+)调试器比MFC更好地可视化了STL。(AUTOEXP.DAT魔法可以解决这个问题,但是很繁琐!当你搞砸它时,没有什么比调试你的调试器更糟糕的了...)

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


2
是的,当涉及到STL时,我非常喜欢VS2008调试器。以前我使用的是VC6,转换到VS2008后使我的生活变得更加轻松。 - Naveen
2
我最近发布了一个autoexp.dat的补充,可以实现这一点:http://thetweaker.wordpress.com/2010/01/11/visualizing-mfc-containers-in-autoexp-dat/ - Ofek Shilon

6
我总是更喜欢使用标准/兼容的库,因为我可能会有未来的项目可以重用部分代码。我不知道未来的项目会使用哪些库,但如果我使用标准/兼容的东西,我就有更好的机会使我的代码可重用。
此外,我使用一个库的次数越多,我就越熟悉它,也越快。如果我要投入时间学习一个库,我希望确保它将会持续存在,并且不会与特定平台或框架绑定。
当然,我说这些话时假设我的选择在性能、功能和易用性方面相当类似。例如,如果MFC类在这些方面有显著的改进,我会使用它们。

5

MFC容器继承自CObject,而CObject的赋值运算符是私有的。在实践中,我发现这非常令人恼火。

std::vectorCArray不同,保证其内存块是连续的,因此您可以轻松地与C编程接口进行交互:

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

CArray保证连续的内存分配:“即使某些元素为空,内存也会按照上限连续分配。” http://msdn.microsoft.com/zh-cn/library/4h2f09ct.aspx - Rob Kennedy

5

事实上,您也可以在一些MFC容器上使用STL算法。然而,由于许多第三方库(如Boost、arabica、Crypto++、utf-cpp等)是为STL设计的,不了解MFC容器,因此STL容器更受欢迎,这是另一个非常实用的原因。


4

现在假设C++开发者至少对STL有些了解。但是对于MFC容器并非如此。因此,如果您要向团队中添加新的开发人员,那么找到一个熟悉STL而不是MFC容器的人将更容易,因此他们可以立即为项目做出贡献。


3

我认为问题归结为一个简单的问题:你更信任谁?如果你信任微软,那么继续使用MFC变体。如果你信任行业,那么使用STL。

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


3
这是一个通常情况下成立的观点,但在这种特定情况下并不适用:他已经广泛使用MFC了,将MFC容器替换为STL对于增强应用程序的可移植性贡献甚微。 - Nemanja Trifunovic
7
Microsoft负责其自有编译器上的MFC和STL,因此这不是一个争论点。我从未发现这两种范例的可靠性有所不同。 - Mark Ransom
好主意。但你可以随时使用第三方库。 - Will Bickford
我唯一的评论是:MFC 在微软公司实际上已经成为了一个死胡同吗?我记得两年前(当我最后一次为个人电脑编程时),MFC 不被推荐用于新开发。 - Michael Kohne
@MichaelKohne,现在是2018年,使用Visual Studio 2017,MFC仍然是Visual Studio产品的一部分。MFC的问题在于其界面看起来有些过时,同时需要Win32 API以及MFC DLL。另一方面,同一个MFC应用程序可以在Windows 10上运行,也可以回溯到Windows XP,并且源代码可以使用Visual Studio 6.x编译到Visual Studio 2017。 - Richard Chambers

2
这是一个使用任何适合您所需工作的工具的案例,“更好”的概念是主观的。
如果您需要将容器与其他符合标准的代码一起使用,或者它将成为跨平台共享的代码,则STL容器可能是更好的选择。
如果您确信您的代码将保持在MFC领域,并且MFC容器适用于您,为什么不继续使用它们呢?
STL容器并不比MFC容器本质上更好,但由于它们是标准的一部分,因此在更广泛的上下文中更有用。

3
在我的职业生涯中,我曾经多次听到过“那永远不可能被移植”,但实际上这种说法常常被证明是错误的。 - sbi

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