Вы бы смешали MFC с STL? Почему?
МФЦ и STL
Ответы (14)
Конечно. Почему нет?
Я использую MFC в качестве уровня представления, хотя структуры и классы в серверной части используют STL.
Используйте STL, когда можете, используйте MFC, когда нет альтернативы
Я их все время смешиваю. Единственным второстепенным PITA была сериализация — контейнеры MFC (CArray, CList, CStringArray и т. д.) поддерживают сериализацию CArchive, но при использовании контейнеров STL вы должны накатывать свой собственный код. В конце концов я переключился на использование boost::serialization и избавился от материала MFC CArchive.
Да, я смешивал их раньше без проблем. Однако после более десяти лет использования MFC я бы никогда не подумал об использовании его для нового проекта.
Я использую MFC для всех своих проектов на C++, поскольку ни один из моих проектов не является консольным. MFC — элегантное решение для разработчиков Windows C++. Я ненавижу QT и не буду использовать WX в Windows. Меня не волнует переносимость, так как мои приложения только для Windows. Мне нравится класс CString MFC/ATL, std::string очень сырой, в нем нет никаких функций "String". std::string это не что иное, как vector<char>.
Для хранения всех данных и алгоритмов я использую STL. Я также использую классы шаблонов ConcRT PPL, которые очень похожи на STL.
Для коллекций на уровне данных. У меня нет данных, подтверждающих это, но я подозреваю, что шаблонные коллекции STL более производительны, чем их аналоги MFC.
Да, я смешиваю их, потому что считаю MFC слишком громоздким для нормального естественно выглядящего С++. Хотя вам, возможно, придется написать некоторый код для преобразований, когда ваш код STL взаимодействует с кодом MFC.
Это была очень плохая идея до (почти) полной поддержки стандарта C++ в Visual Studio 2003. Теперь это совсем не плохая идея. Будет ли это хорошей идеей, зависит от контекста и набора навыков вашей команды.
Да, если выполняются оба следующих условия:
1) Язык, выбранный для проекта, — C++ (который, конечно же, включает STL — буква S в STL означает «Стандартный»).
2) После тщательного анализа не найдено и не считается лучшей альтернативы для поддержки графического интерфейса, чем MFC, и моя команда разработчиков идет на это.
Это зависит от вашего определения «смешивания». Если вы просто имеете в виду создание проекта, использующего как STL, так и MFC, я не вижу в этом никакого вреда. Они служат другой цели.
при смешивании STL с другими заголовками Microsoft обязательно определите NOMINMAX, иначе ваша функция std::min будет искажена синтаксической ошибкой из-за макроса min(a,b).
Вы не должны использовать стандартные исключения в приложении MFC — ваше приложение может зависнуть, если вы добавите его в диалоговое окно. См. этот вопрос по причинам: Почему мой Приложение MFC зависает, когда я создаю исключение?
У меня была структура со многими полями простого типа (UINT, CString, COLORREF и т. д.). Проект компилировался хорошо.
Затем я добавил, что я добавил CArray в структуру. Это не компилировалось.
Затем я реализовал оператор = и конструктор копирования для этой структуры (один использует другой). Затем он скомпилировался.
Некоторое время спустя, выполняя обслуживание структуры, я провел эксперимент: изменил CArray на std::vector и удалил оператор = и конструктор копирования. Он скомпилировался нормально, и структура хорошо копировалась, где вызывался оператор = или конструктор копирования.
Преимущество в том, что я мог сбросить бесполезную часть кода — подверженную ошибкам и, вероятно, не обновленную, когда кто-то выполнял техническое обслуживание, добавляя поле в структуру! — и я вижу в этом большое преимущество.
ПРИЧИНА:
Почему мне сейчас не нужен конструктор копирования и оператор присваивания =?
Раньше в структуре были только поля простого типа. Так что их можно было копировать. Поскольку все они копируемые, структура становится копируемой. Когда я добавил поле 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 в структуру/класс не потребует от вас реализации функций копирования внутри него только из-за этого нового поля.
Я предпочитаю избегать STL и не использовать его, потому что он был не таким уж стандартным, когда MFC был стандартом де-факто в течение примерно десяти лет. Кроме того, до последних версий Visual C++ (и «стандартного» STL) MFC просто имели лучшую производительность.