你会在IT技术中将MFC与STL混合使用吗?为什么?
好的,为什么不呢?
我使用MFC作为表示层,即使后端的数据结构和类使用STL。
尽可能使用STL,当没有其他选择时再使用MFC。
我经常混用它们。唯一的小麻烦是序列化——MFC容器(CArray
、CList
、CStringArray
等)支持CArchive
序列化,但是使用STL容器时,您必须编写自己的代码。最终,我转而使用boost::serialization
并放弃了MFC的CArchive
。
是的,我之前混合使用它们没有出现过问题。但是,在使用MFC十多年后,我不会考虑在新项目中使用它。
我在所有C++项目中都使用MFC,因为我的项目都不是控制台项目。MFC是Windows C++开发者的优雅解决方案。我讨厌QT,我不会在Windows上使用WX。我不关心可移植性,因为我的应用程序只针对Windows。我喜欢MFC/ATL的类,std::string非常原始,没有任何“字符串”功能。std::string仅仅是< vector<char>。
对于所有数据存储和算法,我使用STL。我也使用ConcRT PPL模板类,它们与STL非常相似。
对于数据层中的集合。我没有数据支持这一点,但我的怀疑是,模板化的STL集合比它们的MFC对应物更具性能。
我有一个包含多个简单类型字段(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是指向vector类本身的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成员字段不需要您在其中实现复制函数,仅因为有了这个新字段。
在 Visual Studio 2003 几乎完全支持 C++ 标准之前,这是一个非常糟糕的想法。现在它已经不再是一个坏主意了。无论它是否是一个好主意,取决于上下文和你的团队技能组合。
这取决于你对“混合”一词的定义。 如果你的意思是创建一个同时使用STL和MFC的项目,我认为这没有任何害处。它们都有着不同的用途。