MFC и STL

Вы бы смешали MFC с STL? Почему?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
0
4 843
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

Ответ принят как подходящий

Конечно. Почему нет?

Я использую MFC в качестве уровня представления, хотя структуры и классы в серверной части используют STL.

Да, я смешиваю их, потому что считаю MFC слишком громоздким для нормального естественного C++. Хотя вам, возможно, придется написать код для преобразований, в котором ваш код STL взаимодействует с кодом MFC.

Я их все время перемешиваю. Единственным второстепенным PITA была сериализация - контейнеры MFC (CArray, CList, CStringArray и т. д.) Поддерживают сериализацию CArchive, но при использовании контейнеров STL вам придется использовать собственный код. В конце концов я переключился на использование boost::serialization и сбросил все материалы MFC CArchive.

Да, я их раньше смешивал без проблем. Однако, проработав более десяти лет с MFC, я бы никогда не подумал об использовании его для нового проекта.

Для коллекций на уровне данных. У меня нет данных, подтверждающих это, но я подозреваю, что шаблонные коллекции STL более производительны, чем их аналоги в MFC.

Да, контейнеры STL быстрее, чем коллекции MFC.

Ron 06.01.2009 15:59

Да, если выполняются оба следующих условия:

1) Для проекта выбран язык C++ (который, конечно же, включает STL - S в STL означает «Стандартный»).

2) После тщательного анализа не было найдено или признано подходящим для поддержки графического интерфейса лучшей альтернативы, чем MFC, и моя команда разработчиков пошла на это.

Это было очень плохой идеей до того, как Visual Studio 2003 (почти) полностью поддержала стандарт C++. Теперь это совсем не плохая идея. Хорошая ли идея зависит от контекста и навыков вашей команды.

Используйте STL, когда можете, используйте MFC, когда нет альтернативы

Это зависит от вашего определения «смешивания». Если вы просто имеете в виду создание проекта, использующего как STL, так и MFC, я не вижу в этом никакого вреда. Они служат другой цели.

при смешивании STL с другими заголовками Microsoft обязательно укажите NOMINMAX, в противном случае ваша функция std :: min будет искажена синтаксической ошибкой из-за макроса min (a, b).

Вы не должны использовать стандартные исключения в приложении MFC - ваше приложение может зависнуть, если вы бросите его в диалоговом окне. См. Этот вопрос по причинам: Почему мое приложение MFC зависает, когда я генерирую исключение?

Я предпочитаю избегать STL и не использовать его, потому что он был не таким стандартным, когда MFC был стандартом де-факто около десяти лет. Также до последних версий Visual C++ (и «стандартного» STL) MFC просто имел лучшую производительность.

Я использую MFC для всех своих проектов на C++, поскольку ни один из моих проектов не является консольным. MFC - элегантное решение для разработчиков Windows C++. Я ненавижу QT и не буду использовать WX в Windows. Меня не волнует переносимость, так как мои приложения предназначены только для Windows. Мне нравится класс CString MFC / ATL, std :: string очень сырой, в нем нет никаких "строковых" функций. std::string - это не что иное, как vector<char>.

Для хранения всех данных и алгоритмов я использую STL. Я также использую классы шаблонов ConcRT PPL, которые очень похожи на STL.

У меня была структура с множеством полей простого типа (UINT, CString, COLORREF и т. д.). Проект компилировался хорошо.

Затем я добавил объект, который добавил в структуру CArray. Это не компилировалось.

Затем я реализовал оператор = и конструктор копирования для этой структуры (один использует другой). Затем он компилируется.

Некоторое время спустя, выполняя обслуживание структуры, я провел эксперимент: изменил 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 в структуру / класс не потребует от вас реализации функций копирования внутри него только из-за этого нового поля.

Другие вопросы по теме