【问题标题】:Mixing MFC and STL [closed]MFC 和 STL [关闭]
【发布时间】:2010-09-29 18:43:39
【问题描述】:

您会将 MFC 与 STL 混合使用吗?为什么?

【问题讨论】:

    标签: c++ mfc stl


    【解决方案1】:

    当然。为什么不呢?

    我使用 MFC 作为表示层,尽管后端的结构和类使用 STL。

    【讨论】:

      【解决方案2】:

      尽可能使用 STL,在别无选择的情况下使用 MFC

      【讨论】:

        【解决方案3】:

        我一直在混合它们。唯一次要的 PITA 是序列化 - MFC 容器(CArrayCListCStringArray 等)支持CArchive 序列化,但是当使用 STL 容器时,您必须滚动自己的代码。最后我改用boost::serialization 并转储了MFC CArchive 的东西。

        【讨论】:

          【解决方案4】:

          是的,我以前混合过它们没有问题。然而,在使用 MFC 十多年后,我再也不会考虑将它用于新项目。

          【讨论】:

            【解决方案5】:

            我的所有 C++ 项目都使用 MFC,因为我的所有项目都不是控制台。 MFC 是适用于 Windows C++ 开发人员的优雅解决方案。我讨厌 QT,我不会在 Windows 上使用 WX。我不关心可移植性,因为我的应用程序仅适用于 Windows。我喜欢 MFC/ATL 的 CString 类,std::string 非常原始,其中没有任何“字符串”功能。 std::string 只不过是 vector<char>

            对于所有数据存储和算法,我使用 STL。我也使用 ConcRT PPL 模板类,它与 STL 非常相似。

            【讨论】:

              【解决方案6】:

              用于数据层中的集合。我没有数据支持这一点,但我怀疑模板化的 STL 集合比它们的 MFC 对应物性能更高。

              【讨论】:

              • 是的,STL 容器比 MFC 集合更快。
              【解决方案7】:

              是的,我确实混合了它们,因为我发现 MFC 对于正常的自然外观 c++ 来说太笨拙了。虽然您可能需要编写一些代码来进行 STL 代码与 MFC 代码对话的转换。

              【讨论】:

                【解决方案8】:

                在 Visual Studio 2003(几乎)完全支持 C++ 标准之前,这是一个非常糟糕的主意。现在这根本不是一个坏主意。这是否是一个好主意取决于环境和团队的技能。

                【讨论】:

                  【解决方案9】:

                  是的,如果以下两个条件都成立:

                  1) 为项目选择的语言是 C++(当然,它包括 STL - STL 中的 S 代表“标准”)。

                  2) 经过仔细分析,没有找到或认为比 MFC 更适合 GUI 支持的替代方案,我的开发团队就这样做了。

                  【讨论】:

                    【解决方案10】:

                    这取决于您对“混合”的定义。 如果您只是想创建一个同时使用 STL 和 MFC 的项目,我认为这没有任何危害。它们用于不同的目的。

                    【讨论】:

                      【解决方案11】:

                      在将 STL 与其他微软头文件混合时,一定要定义 NOMINMAX, 否则你的 std::min 函数会因为 min(a,b) 宏而出现语法错误。

                      【讨论】:

                        【解决方案12】:

                        您不应在 MFC 应用程序中使用标准异常 - 如果您将其扔到对话框中,您的应用程序可能会挂起。看这个问题的原因:Why does my MFC app hang when I throw an exception?

                        【讨论】:

                          【解决方案13】:

                          我有一个包含许多简单类型字段(UINT、CString、COLORREF 等)的结构。项目编译良好。

                          然后我添加了一个 CArray 到结构中。它没有编译。

                          然后我为该结构实现了 operator= 和复制构造函数(一个使用另一个)。然后编译。

                          一段时间后,对结构进行维护,我做了一个实验:将 CArray 更改为 std::vector 并删除 operator= 和复制构造函数。它编译得很好,并且在调用 operator= 或复制构造函数的地方很好地复制了结构。

                          优点是我可以转储代码中无用的部分——容易出错,并且当有人在结构中添加字段时可能不会更新! — 我认为这是一个很大的优势。

                          原因:

                          为什么我现在不需要复制构造函数和 = 赋值运算符?

                          以前,结构只有简单的类型字段。所以它们是可以复制的。由于它们都是可复制的,因此结构可复制。当我添加 CArray 字段时,这个是不可复制的,因为 CArray 派生自 CObject,一个明确地将这两个函数设为私有的类:

                          class AFX_NOVTABLE CObject
                          {
                              //...
                          
                              private:
                                  CObject(const CObject& objectSrc);              // no implementation
                                  void operator=(const CObject& objectSrc);       // no implementation
                          
                              //...
                          }
                          

                          CArray 是从 CObject 派生的类,不会做任何事情来覆盖此行为,因此 CArray 将继承它并使其自身不可复制。在使我的结构可复制之前添加了一个 CArray,我收到了错误:

                          c:\program files\microsoft visual studio 8\vc\atlmfc\include\afxtempl.h(272) : error C2248: 'CObject::operator =' : cannot access private member declared in class 'CObject'
                              c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(554) : see declaration of 'CObject::operator ='
                              c:\program files\microsoft visual studio 8\vc\atlmfc\include\afx.h(524) : see declaration of 'CObject'
                              This diagnostic occurred in the compiler generated function 'CArray<TYPE,ARG_TYPE> &CArray<TYPE,ARG_TYPE>::operator =(const CArray<TYPE,ARG_TYPE> &)'
                              with
                              [
                                  TYPE=unsigned int,
                                  ARG_TYPE=unsigned int &
                              ]
                          

                          std::vector 可以根据自己的定义进行复制:

                                  // TEMPLATE CLASS vector
                          template<class _Ty,
                              class _Ax = allocator<_Ty> >
                              class vector
                                  : public _Vector_val<_Ty, _Ax>
                              {   // varying size array of values
                          public:
                              typedef vector<_Ty, _Ax> _Myt;    
                          

                          注意 _Myt 是向量类本身的 typedef。

                              //...
                          
                              vector(const _Myt& _Right)
                                  : _Mybase(_Right._Alval)
                                  {   // construct by copying _Right
                                  if (_Buy(_Right.size()))
                                      _TRY_BEGIN
                                      this->_Mylast = _Ucopy(_Right.begin(), _Right.end(),
                                          this->_Myfirst);
                                      _CATCH_ALL
                                      _Tidy();
                                      _RERAISE;
                                      _CATCH_END
                                  }
                          
                              //...
                          
                              vector(_Myt&& _Right)
                                  : _Mybase(_Right._Alval)
                                  {   // construct by moving _Right
                                  _Assign_rv(_STD forward<_Myt>(_Right));
                                  }
                          
                              _Myt& operator=(_Myt&& _Right)
                                  {   // assign by moving _Right
                                  _Assign_rv(_STD forward<_Myt>(_Right));
                                  return (*this);
                                  }
                          
                              //...
                           }
                          

                          因此,将 std::vector 成员字段添加到结构/类将不需要您在其中实现复制功能,只是因为该新字段。

                          【讨论】:

                            【解决方案14】:

                            我宁愿避免使用 STL,也不使用它,因为当 MFC 成为事实上的标准大约十年时,它曾经不是那么标准。此外,直到最新版本的 Visual C++(和“标准”STL),MFC 才具有更好的性能。

                            【讨论】:

                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2011-10-09
                              • 2011-05-06
                              • 1970-01-01
                              • 2010-09-20
                              • 2014-10-18
                              • 2010-09-15
                              相关资源
                              最近更新 更多