Главная » Статьи » C++ » Общие сведения

Достоинства и недостатки языка С++
Прежде всего, необходимо подчеркнуть, что оценивать достоинства и, в особенности, недостатки С++ необходимо в контексте тех принципов, на которых строился язык, и требований, которые к нему изначально предъявлялись.
 
Достоинства

C++ — чрезвычайно мощный язык, содержащий средства создания эффективных программ практически любого назначения, от низкоуровневых утилит и драйверов до сложных программных комплексов самого различного назначения. В частности:
Поддерживаются различные стили и технологии программирования, включая традиционное директивное программирование, ООП,
Имеется возможность работы на низком уровне с памятью, адресами, портами.
Возможность создания обобщённых алгоритмов для разных типов данных, их специализация и вычисления на этапе компиляции, используя шаблоны.
Кроссплатформенность. Доступны компиляторы для большого количества платформ, на языке C++ разрабатывают программы для самых различных платформ и систем.
Эффективность. Язык спроектирован так, чтобы дать программисту максимальный контроль над всеми аспектами структуры и порядка исполнения программы. Ни одна из языковых возможностей, приводящая к дополнительным накладным расходам, не является обязательной для использования — при необходимости язык позволяет обеспечить максимальную эффективность программы.

 
Недостатки

Отчасти недостатки C++ унаследованы от языка-предка — Си, — и вызваны изначально заданным требованием возможно большей совместимости с Си. Это такие недостатки, как:
Синтаксис, провоцирующий ошибки:
Операция присваивания обозначается как = , а операция сравнения как ==. Их легко спутать, при этом операция присваивания возвращает значение, поэтому присваивание на месте выражения является синтаксически корректным, а в конструкциях цикла и ветвления появление числа на месте логического значения также допустимо, так что ошибочная конструкция оказывается синтаксически правильной. Типичный пример подобной ошибки:
if (x=0) { операторы }
Здесь в условном операторе по ошибке написано присваивание вместо сравнения. В результате, вместо того, чтобы сравнить текущее значение x с нулём, программа присвоит x нулевое значение, а потом интерпретирует его как значение условия в операторе if. Так как нуль соответствует логическому значению «ложь» (false), блок операторов в условной конструкции не выполнится никогда. Ошибки такого рода трудно выявлять, но во многих современных компиляторах предлагается диагностика некоторых подобных конструкций.
Операции присваивания (=), инкрементации (++), декрементации (--) и другие возвращают значение. В сочетании с обилием операций это позволяет, хотя и не обязывает, создавать трудночитаемые выражения. Наличие этих операций в Си было вызвано желанием получить инструмент ручной оптимизации кода, но в настоящее время оптимизирующие компиляторы обычно генерируют оптимальный код и на традиционных выражениях. С другой стороны, один из основных принципов языков C и C++ — позволять программисту писать в любом стиле, а не навязывать «хороший» стиль.
Макросы (#define) являются мощным, но опасным средством. Они сохранены в C++ несмотря на то, что необходимость в них, благодаря шаблонам и встроенным функциям, не так уж велика. В унаследованных стандартных С-библиотеках много потенциально опасных макросов.
Некоторые преобразования типов неинтуитивны. В частности, операция над беззнаковым и знаковым числами выдаёт беззнаковый результат.
Необходимость записывать break в каждой ветви оператора switch и возможность последовательного выполнения нескольких ветвей при его отсутствии провоцирует ошибки из-за пропуска break. Эта же особенность позволяет делать сомнительные «трюки», базирующиеся на избирательном неприменении break и затрудняющие понимание кода.
Препроцессор, унаследованный от С, очень примитивен. Это приводит с одной стороны к тому, что с его помощью нельзя (или тяжело) осуществлять некоторые задачи метапрограммирования, а с другой, вследствие своей примитивности, он часто приводит к ошибкам и требует много действий по обходу потенциальных проблем. Некоторые языки программирования (например, Scheme и Nemerle) имеют намного более мощные и более безопасные системы метапрограммирования (также называемые макросами, но мало напоминающие макросы С/С++).
Плохая поддержка модульности (по сути, в классическом Си модульность на уровне языка отсутствует, её обеспечение переложено на компоновщик). Подключение интерфейса внешнего модуля через препроцессорную вставку заголовочного файла (#include) серьёзно замедляет компиляцию при подключении большого количества модулей (потому что результирующий файл, который обрабатывается компилятором, оказывается очень велик). Эта схема без изменений скопирована в C++. Для устранения этого недостатка, многие компиляторы реализуют механизм прекомпиляции заголовочных файлов Precompiled Headers.

К собственным недостаткам C++ можно отнести:
Сложность и избыточность, из-за которых C++ трудно изучать, а построение компилятора сопряжено с большим количеством проблем. В частности:
В языке практически полностью сохранён набор конструкций Си, к которому добавлены новые средства. Во многих случаях новые средства и механизмы позволяют делать то же самое, что и старые, но в языке сохраняются оба варианта.
Поддержка множественного наследования реализации в ООП-подсистеме языка вызывает целый ряд логических проблем, а также создаёт дополнительные трудности в реализации компилятора.
Шаблоны в своём исходном виде приводят к порождению кода очень большого объёма, а введённая позже в язык возможность частичной спецификации шаблонов трудно реализуема и не поддерживается многими существующими компиляторами.
Недостаток информации о типах данных во время компиляции (CTTI).
Метапрограммирование на основе шаблонов C++ сложно и при этом ограничено в возможностях. Оно состоит в реализации средствами шаблонов C++ интерпретатора примитивного функционального языка программирования выполняющегося во время компиляции. Сама по себе данная возможность весьма привлекательна, но такой код весьма трудно воспринимать и отлаживать. Языки Lisp/Scheme, Nemerle и некоторые другие имеют более мощные и одновременно более простые для восприятия подсистемы метапрограммирования. Кроме того, в языке D реализована сравнимая по мощности, но значительно более простая в применении подсистема шаблонного метапрограммирования.
Хотя декларируется, что С++ мультипарадигменный язык, реально в языке отсутствует поддержка функционального программирования. Отчасти, данный пробел устраняется различными библиотеками (Loki, Boost) использующими средства метапрограммирования для расширения языка функциональными конструкциями (например, поддержкой лямбд/анонимных методов), но качество подобных решений значительно уступает качеству встроенных в функциональные языки решений. Такие возможности функциональных языков, как сопоставление с образцом, вообще крайне сложно эмулировать средствами метапрограммирования.
Некоторые считают недостатком языка C++ отсутствие встроенной системы сборки мусора. С другой стороны, в C++ имеется достаточно средств, позволяющих почти исключить использование опасных указателей, нет принципиальных проблем и в реализации и использовании сборки мусора (на уровне библиотек, а не языка). Отсутствие встроенной сборки мусора позволяет пользователю самому выбрать стратегию управления ресурсами.

Категория: Общие сведения | Добавил: user (09.05.2009) | Автор: user
Просмотров: 19235 | Комментарии: 3 | Рейтинг: 5.0/1
Всего комментариев: 3
1 Liska  
Читаю и чувствую себя как дома. Спасибо создателям за хороший ресурс!

2 Infejuffesoni  
Данный пост — одно из редких исключений, когда читаешь с удовольствием и что-то для себя выносишь. Спасибо автору. Добавлю в избранноеhttp://voronezh.recikl.ru/ - . :)

3 Upholoduple  
Интересная тема

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]