Почему контейнеры STL предпочтительнее контейнеров MFC?
Ранее я использовал классы коллекции MFC, такие как CArray
а также CMap
, Через некоторое время я переключился на контейнеры STL и некоторое время использовал их. Хотя STL мне кажется намного лучше, я не могу точно определить точные причины этого. Некоторые из рассуждений, таких как:
- Требуется MFC: не выполняется, потому что другие части моей программы используют MFC
- Это зависит от платформы: не работает, потому что я запускаю свое приложение только на Windows (нет необходимости в переносимости)
- Это определено в стандарте C++: ОК, но контейнеры MFC все еще работают
Единственная причина, по которой я могу придумать, заключается в том, что я могу использовать алгоритмы для контейнеров. Есть ли какая-то другая причина, по которой я здесь скучаю - что делает контейнеры STL лучше контейнеров MFC?
13 ответов
Рональд Лереманс, менеджер отдела продуктов VC++, даже сказал, что будет использовать STL в июне 2006 года:
И, честно говоря, команда даст вам тот же ответ. Классы коллекции MFC существуют только для обратной совместимости. C++ имеет стандарт для классов коллекций, и это библиотека стандартов C++. Технического недостатка для использования любой стандартной библиотеки в приложении MFC нет.
Мы не планируем вносить существенные изменения в этой области.
Рональд Лереманс
Исполняющий обязанности руководителя отдела продукции
Visual C++ Team
Однако в какой-то момент, когда я работал над кодом, который выполнялся на этапе установки Windows, мне не разрешили использовать контейнеры STL, но вместо этого мне сказали использовать контейнеры ATL (на самом деле CString
в частности, который, я думаю, на самом деле не контейнер). Объяснение состояло в том, что контейнеры STL имели зависимости от битов времени выполнения, которые могли фактически не быть доступными во время выполнения кода, в то время как эти проблемы не существовали для коллекций ATL. Это довольно особый сценарий, который не должен затрагивать 99% кода.
Контейнеры STL:
- Иметь гарантии исполнения
- Может использоваться в алгоритмах STL, которые также имеют гарантии производительности
- Может использоваться сторонними библиотеками C++, такими как Boost
- Стандартны и, скорее всего, переживут проприетарные решения
- Поощрять общее программирование алгоритмов и структур данных. Если вы пишете новые алгоритмы и структуры данных, соответствующие STL, вы можете использовать то, что STL уже предоставляет бесплатно.
- Совместимость с другими библиотеками (такими как boost) в синтаксисе, совместимости и парадигме. Это нетривиальное преимущество.
- Использование STL создаст набор навыков, который с большей вероятностью будет полезен в других контекстах. MFC уже не так широко используется; STL есть.
- Использование STL создаст образ мышления, который вы можете (или не можете) найти полезным в написанном вами коде.
Однако использование чего-то другого, кроме STL, не является неправильным.
- STL имеет больше типов коллекций, чем MFC
- Отладчик Visual Studio (2008+) визуализирует STL намного лучше, чем MFC. (Волшебство AUTOEXP.DAT может это исправить - но это боль! Ничего подобного отладке вашего отладчика, когда вы его облажаете...)
Одна хорошая вещь с MFC - то, что там все еще есть большой корпус кода MFC. Другие ответы говорят о сторонней совместимости. Не забывайте сторонние материалы на основе MFC.
Я всегда предпочитаю использовать больше стандартных / совместимых библиотек, где это возможно, поскольку у меня могут быть будущие проекты, в которых я смогу повторно использовать часть кода. Я понятия не имею, какие библиотеки будут использовать будущие проекты, но у меня больше шансов сделать мой код многоразовым, если я использую стандартные / совместимые вещи.
Кроме того, чем больше я использую библиотеку, тем удобнее и быстрее она становится. Если я собираюсь потратить время на изучение библиотеки, я хочу быть уверенным, что она останется и не связана с конкретной платформой или структурой.
Конечно, я говорю все это, предполагая, что мой выбор довольно похож, когда речь идет о производительности, функциях и простоте использования. Например, если классы MFC являются достаточно значительным улучшением в этих областях, я бы использовал их вместо этого.
Контейнеры MFC происходят из CObject
а также CObject
сделал оператор присваивания закрытым. Я нашел это очень раздражающим на практике.
std::vector
Unlinke CArray гарантирует, что блок памяти является смежным, таким образом, вы можете легко взаимодействовать с интерфейсами программирования C:
std::vector<char> buffer;
char* c_buffer = &*buffer.begin();
Фактически, вы можете использовать алгоритмы STL и на некоторых контейнерах MFC. Однако контейнеры STL предпочтительны по другой очень практической причине: многие сторонние библиотеки (Boost, arabica, Crypto++, utf-cpp...) предназначены для работы с STL, но ничего не знают о контейнерах MFC.
Теперь предполагается, что разработчики на C++, по крайней мере, до некоторой степени знакомы с STL. Не так для контейнеров MFC. Поэтому, если вы добавляете в свою команду нового разработчика, вам будет легче найти того, кто знает STL, а не контейнеры MFC, и, таким образом, сможет немедленно внести свой вклад.
Я думаю, что все сводится к простому вопросу: кому ты больше доверяешь? Если вы доверяете Microsoft, то продолжайте использовать варианты MFC. Если вы доверяете отрасли, то используйте STL.
Я голосую за STL, потому что код, который работает сегодня под Windows, возможно, завтра придется перенести на другую платформу.:)
Потому что библиотека, которая использует итераторы для объединения последовательностей любого вида с алгоритмами, так что A) возможны все разумные перестановки и B) она универсально расширяема, является (когда вы думаете о своей концепции библиотеки контейнеров, как это было 15 лет назад) такой ошеломляюще удивительная идея, что она в значительной степени вылетела из воды всего за менее чем десятилетие?
Серьезно, у STL есть свои недостатки (почему бы не диапазоны вместо итераторов? И эта идиома удаления-удаления не совсем хороша), но она основана на блестящей идее, и есть очень веские причины, по которым нам не нужно изучать новый контейнер / Библиотека алгоритмов каждый раз, когда мы начинаем на новой работе.
Наряду с упомянутыми аспектами: хорошо поддерживаемый, стандартный доступный, оптимизированный для производительности, разработанный для использования с алгоритмами, я мог бы добавить еще один аспект: безопасность типов и множество проверок во время компиляции. Вы даже не можете себе представить рисование double
из std::set<int>
,
Я бы не стал полностью отклонять аргумент о переносимости. То, что вы сегодня используете MFC, не означает, что вы будете всегда. И даже если вы в основном пишете для MFC, часть вашего кода может быть повторно использована в других приложениях, если она будет более общей и основанной на стандартах.
Я думаю, что другой причиной для рассмотрения STL является то, что его дизайн и развитие извлекли выгоду из библиотек, которые были до этого, включая MFC и ATL. Многие из этих решений более чисты, более пригодны для повторного использования и менее подвержены ошибкам. (Хотелось бы, чтобы у них было лучшее соглашение об именах.)
Это тот случай, когда какой-либо инструмент подходит для той работы, которую вы хотите сделать, и "лучше" - это субъективный термин.
Если вам нужно использовать ваши контейнеры с другим совместимым со стандартами кодом, или если это когда-либо будет код, который используется для всех платформ, контейнеры STL, вероятно, будут лучшим выбором.
Если вы уверены, что ваш код останется в MFC-land, и контейнеры MFC будут работать на вас, почему бы не продолжать их использовать?
Контейнеры STL по своей природе не лучше контейнеров MFC, однако, поскольку они являются частью стандарта, они более полезны в более широком диапазоне контекстов.