МФЦ и СТЛ - PullRequest
       71

МФЦ и СТЛ

10 голосов
/ 06 января 2009

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

Ответы [ 14 ]

20 голосов
/ 06 января 2009

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

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

8 голосов
/ 03 февраля 2009

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

6 голосов
/ 06 января 2009

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

2 голосов
/ 16 февраля 2012

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

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

2 голосов
/ 06 января 2009

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

1 голос
/ 06 января 2009

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

0 голосов
/ 01 августа 2015

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

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

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

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

0 голосов
/ 28 января 2012

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

0 голосов
/ 14 декабря 2011

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

0 голосов
/ 14 декабря 2011

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

...