C ++

редактировать
Язык программирования общего назначения

C ++
ISO C ++ Logo.svg Логотип C ++, одобренный Стандартным C ++
Парадигмы Мультипарадигма : процедурный, функциональный, объектно-ориентированный, общий, модульный
СемействоC
Разработано Бьярном Страуструпом
Разработчик ISO / IEC JTC1 (Объединенный технический комитет 1) / SC22 (Подкомитет 22) / WG21 (Рабочая группа 21)
Первое появление1985; 35 лет назад (1985 г.)
Стабильный выпуск C ++ 17 (ISO / IEC 14882: 2017) / 1 декабря 2017 г.; 2 года назад (01.12.2017)
Предварительный выпуск C ++ 20
Дисциплина ввода Статический, именительный падеж, частично выведенный
OS Наиболее важные
Расширения имен файлов .C,.cc,.cpp,.cxx,.c ++,.h,.hh,.hpp,.hxx,.h ++
Веб-сайтisocpp.org
Основные реализации
GCC, LLVM Clang, Microsoft Visual C ++, Embarcadero C ++ Builder, Компилятор Intel C ++, IBM XL C ++, EDG
Под текущей
Ada, АЛГОЛ 68, C, CLU,ML, Mesa, Modula-2, Simula, Smalltalk
Под их
Ada 95, C#,C99, Chapel, Clojure,D, Java, JS ++, Lua, Nim, Perl, PHP, Python, Rust, Seed7

C ++ () - язык программирования общ его назначение, созданный Бьярном Страуструпом как расширение языка программирования C или «C с классами ». Язык значительно расширился со временем, и современный C ++ теперь имеет объектно-ориентированные, общие и функциональные функции в дополнение к средствам для низко- уровень память манипуляции. Он почти всегда реализуется как скомпилированный язык, многие поставщики предоставляют компиляторы C ++, включая Free Software Foundation, LLVM, Microsoft, Intel, Oracle и IBM, поэтому он доступен на платформе многих.

C ++ разработан для склонности к системному программированию и встроенному, программному обеспечению с ограниченными ресурсами и большим системам с производственной, эффективностью и гибкость использования, как подчеркивается в его конструкции. C ++ также является полезным во многих других контекстах, являющимися серверами ограниченных приложений, включая настольные приложения, >, ( например, электронная коммерция, веб-поиск или SQL серверы) и приложения, критичные к производительности (например, телефонные коммутаторы или космические зонды ).

C ++ стандартизирован Международная организация по стандартизации (ISO), последняя версия стандарта ратифицирована и опубликована ISO в декабре 2017 года как ISO / IEC 14882: 2017 (неофициально Язык программирования C ++ был известным стандартизирован в 1998 году как ISO / IEC 14882: 1998, который затем был изменен посредством C ++ 03, <C ++ 17 ). 319>Стандарты C ++ 11 и C ++ 14. Текущий стандарт C ++ 17 заменяет их новыми функциями и расширенной стандартной библиотекой. До начала года стандартизации в 1998 году C ++ был разработан датской компьютерный ученый Бьярн Страуструп в Bell Labs с 1979 года как расширение языка C ; ему нужен был эффективный и гибкий язык, подобный C, который также предоставлял высокоуровневые функции для организации программ. С 2012 года C ++ находится на трехлетнем графике выпуска, и следующим запланированным стандартом станет C ++ 20 (а затем C ++ 23 ).

Содержание

  • 1 История
    • 1.1 Этимология
    • 1.2 Философия
    • 1.3 Стандартизация
  • 2 Язык
    • 2.1 Хранение объектов
      • 2.1.1 Объекты длительности статического хранения
      • 2.1.2 Объекты продолжительности хранения потока
      • 2.1.3 Автоматически объекты продолжительности хранения
      • 2.1.4 Объекты продолжительности динамического хранения
    • 2.2 Шаблоны
    • 2.3 Объекты
      • 2.3.1 Инкапсуляция
      • 2.3.2 Наследование
    • 2.4 Операторы и перегрузка операторов
    • 2.5 Полиморфизм
      • 2.5.1 Статический полиморфизм
      • 2.5.2 Динамический полиморфизм
        • 2.5.2.1 Наследование
        • 2.5.2.2 Виртуальные функции-члены
    • 2.6 Лямбда-выражения
    • 2.7 Обработка исключений
  • 3 Стандартная библиотека
  • 4 Основные принципы C ++
  • 5 Совместимость
    • 5.1 с C
  • 6 Критика
  • 7 См. Также
  • 8 Ссылки
  • 9 Дополнитель наярна
  • 10 Внешние ссылки

История

Бьярн Страуструп, создатель C ++, в своем офисе ATT в Нью-Джерси c. 2000

В 1979 году Бьярн Страуструп, датский компьютерный ученый, начал работу над «C с классами », предшественником C ++. Мотивация к созданию нового языка возникла из опыта Страуструпа в программировании для его докторской диссертации. Страуструп обнаружил, что Simula имеет функции, которые были очень полезны для крупномасштабной разработки программного обеспечения, но язык был слишком медленным для практического использования, в то время как BCPL был быстрым, но слишком низкоуровневым, чтобы подходить для крупной разработки программного обеспечения. Когда Страуструп начал работать в ATT Bell Labs, у него возникла проблема анализа UNIX ядра в отношении распределенных вычислений. Вспоминая его докторскую степень. Благодаря опыту, Страуструп решил усовершенствовать язык C с помощью функций, подобных Simula. C выбран потому, что он был универсальным, быстрым, портативным и широко используемым. Помимо C и влияния Simula, другие языки также повлияли на этот новый язык, включая ALGOL 68, Ada, CLU и ML.

Первоначально "C" Страуструпа с Классы »добавлены функции к компилятору C, Cpre, включая классы, производные классы, строгая типизация, встраивание и аргументы по По умолчанию.

В 1982 году Страуструп начал работать преемника C с классами, которые он назвал «C ++» (++- это оператор увеличения в C) после прохождения нескольких других имен. Были добавлены новые функции, в том числе виртуальные функции, имя функции и перегрузка оператора, ссылки, константы, безопасное для типов функций выделения памяти со свободным хранением (новое / удаление), улучшенная проверка типов и однострочные комментарии в стиле BCPL с двумя косыми чертами (//). Кроме того, Страуструпал разработал новый автономный компилятор для C ++, Cfront.

. В 1984 году Страуструп реализовал первую библиотеку потокового ввода / вывода. Идея конвейера вывода вывода, а не именованной функции вывода была предложена Дугом Макилроем (который ранее предлагал который был предложен Unix ).

В 1985 году было выпущено первое Язык программирования C ++, которое стало окончательным справочником по языку, поскольку официального стандарта еще не существовало. Первая коммерческая реализация C ++ была выпущена в октябре того же года.

В 1989 году был выпущен C ++ 2.0, последовало обновленное второе издание языка программирования C ++ в 1991 году. Новые функции в 2.0 включают множественное наследование, абстрактные классы, статические функции-члены, константные функции-члены и защищенные члены. В 1990 году было опубликовано Справочное руководство по C ++ с комментариями. Эта работа стала стандартом стандарта. Более поздние дополнения к функциям включали шаблоны, исключения, пространства имен, новые приведения и логический тип.

Тест на Функции C ++ 11, представленные в Париже в 2015 г.

В 1998 г. был выпущен C ++ 98, стандартизирующий язык, а в 2003 г. было выпущено небольшое обновление (C ++ 03 ).

После C ++ 98 C ++ развивался относительно медленно, пока в 2011 году не был выпущен стандарт C ++ 11, добавив множество новых функций, дальнейшее расширение стандартной библиотеки и предоставление дополнительных возможностей. программистам на C ++. После незначительного обновления C ++ 14, выпущенного в декабре 2014 г., в C ++ 17 были внесены различные новые дополнения. Техническая доработка стандарта C ++ 20 состоялась в феврале 2020 года, а проект был утвержден 4 сентября 2020 года; ожидается, что он будет опубликован к концу 2020 года.

По состоянию на 2019 год C ++ является четвертым по использованию языка программирования после Java, C и Python.

3 января 2018 года Страуструп был объявлен лауреатом Премии Чарльза Старка Дрейпера в области инженерии в 2018 г. «За концептуализацию и приложение языка программирования C ++».

Этимология

Согласно Страуструпу, «название означает эволюционный характер изменений от C». Это имя приписывается Рику Маскитти (середина 1983 г.) и впервые было использовано в декабре 1983 г. Когда в 1992 г. Маскитти был неофициально допрошен по названию, он указал, что оно было дано в иронии дух. Название происходит от оператора ++языка C (который увеличивает значение модели ) и общего соглашения об именах использования "+ "для обозначения расширенной компьютерной программы.

В период разработки C ++ этот язык узнался как «новый C» и «C с классами» до того, как получил свое окончательное название.

Философия

На протяжении всей жизни C ++ его развитие и эволюция руководствовались набором принципов:

  • Он должен определяться реальными проблемами, а его функции должны быть полезны в реальном мире программ.
  • Каждая функция должна быть реализована (с достаточно очевидным способом сделать это).
  • Программисты должны иметь свой собственный стиль программирования, и этот стиль должен полностью поддерживаться C ++.
  • Разрешение полезной функции более важно, чем предотвращение любого возможного неправильного использования C ++.
  • Специальные средства для организации разработки отдельных частей.
  • Никаких неявных нарушений системы типов (но допускаются явные нарушения; то есть те, которые явно запрошены программистом).
  • Типы, созданные пользователем, должны иметь ту же поддержку и возможности, что и встроенные типы.
  • Неиспользуемые функции не отрицательно влиять на создание исполняемые файлы (например, с меньшей производительностью).
  • Не должно быть языка ниже C ++ (кроме языка асслера ).
  • C ++ должен работать вместе с другими существующими языками программирования, вместо того, чтобы использовать свои собственные собственные отдельные отдельные язычки и несовместимая среда программирования.
  • Если указано намерение программиста неизвестно, разрешите программисту указать его, предоставив ручное управление.

Стандартизация

Сцена во время согласования стандартов C ++ в Стокгольме в 1996 г.
Стандарты C ++
ГодСтандарт C ++Неофициальное название
1998ISO / IEC 14882: 1998C + + 98
2003ISO / IEC 14882: 2003C ++ 03
2011ISO / IEC 14882: 2011C ++ 11, C ++ 0x
2014ISO / IEC 14882: 2014C ++ 14, C ++ 1y
2017ISO / IEC 14882: 2017C ++ 17, C ++ 1z
2020подлежит определениюC ++ 20, C ++ 2a

C + + стандартизован Рабочая группа ISO, известная как JTC1 / SC22 / WG21. На данный момент опубликовано пять видов данного стандарта C ++, C ++ 20.

В 1998 году рабочая группа ISO впервые стандартизировала C ++ как ISO / IEC 14882: 1998, который неофициально известен как С ++ 98. В 2003 году он опубликовал новую версию стандарта C ++ под названием ISO / IEC 14882: 2003, в которой исправлены проблемы, выявленные в C ++ 98.

Следующая основная версия стандарта неофициально называлась «C ++ 0x», но была выпущена только в 2011 году. C ++ 11 (14882: 2011) включил в себя много дополнений как к основному языку, так и к стандартной библиотеке.

В 2014 году C ++ 14 (также известный как C ++ 1y) был выпущен как небольшое расширение для C ++ 11, в основном с исправлениями ошибок и небольшие улучшения. Процедура по международному проекту стандарта завершилась в середине августа 2014 года.

После C ++ 14 основная версия C ++ 17, неофициально известная как C ++ 1z, была завершена комитет ISO C ++ в середине июля 2017 г. и был утвержден и опубликован в декабре 2017 г.

В рамках процесса стандартизации ISO также публикует технические отчеты и спецификации :

  • ISO / IEC TR 18015: 2006 об использовании C ++ во встроенных системах и о влиянии на функциональные функции языка и библиотеки C ++,
  • ISO / IEC TR 19768: 2007 (также известный как Технический отчет C ++ 1 ) по библиотеке расширения, в основном интегрированные в C ++ 11,
  • ISO / IEC TR 29124: 2010 по специальным математическим функциям,
  • ISO / IEC TR 24733: 2011 по десятичной системе с плавающей запятой арифметике,
  • ISO / IEC TS 18822: 2015 в стандартной библиотеке файловой системы,
  • ISO / IEC TS 19570: 2015 в параллельных версиях алгоритмов стандартной стандартной библиотеки,
  • ISO / IEC TS 19841: 2015 по программному обеспечению tr оперативная память,
  • ISO / IEC TS 19568: 2015 на новом наборе расширений библиотеки, некоторые из которых уже интегрированы в C ++ 17,
  • ISO / IEC TS 19217: 2015 на C + + концепция, интегрированные в C ++ 20
  • ISO / IEC TS 19571: 2016 по расширм библиотеки для параллелизма
  • ISO / IEC TS 19568: 2017 по новому набору общего - целевые расширения библиотеки
  • ISO / IEC TS 21425: 2017 по интегрированным библиотекам для диапазонов, указанные в C ++ 20
  • ISO / IEC TS 22277: 2017 по сопрограммам
  • ISO / IEC TS 19216: 2018 по сетевой библиотеке
  • ISO / IEC TS 21544: 2018 по модулям
  • ISO / IEC TS 19570: 2018 по новому набору расширений библиотеки для параллелизма

Другие технические указаны в разработке и ожидают утверждения, включая статическое отражение.

Язык

Язык C ++ состоит из двух основных компонентов: прямое сопоставление аппаратных функций, предоставляемое в основном подмножеством C, и абстракции с нулевыми накладными расходами, основанные на этих отображениях. Страуструп представил C ++ как «легкий язык программирования с абстракциями [[шаблон] для создания и использования эффективных и элегантных абстракций» »; и «предложение аппаратного доступа и абстракции используется C ++. Эффективное выполнение - вот что отличает его от других языков ».

C ++ наследует большую часть синтаксиса C. Ниже приведена версия Бьярна Страуструпа программы Hello world, которая использует средство потока стандартной библиотеки C ++ для записи сообщений в стандартный вывод :

1 #include 2 3 int main () 4 {5 std :: cout << "Hello, world!\n"; 6 }

Объект хранилища

Как и в C, C ++ поддерживает четыре типа управления памятью : статические объекты продолжительности хранения, продолжительность хранения потока объекты, объекты продолжительности автоматического хранения и объекты продолжительности динамического хранения.

Объекты продолжительности статического хранения

Объекты продолжительности статического хранения последовательности до ввода main ()(см. Исключение ниже) и уничтожается в обратном порядке после выхода из main (). Точный порядок создания не указан в стандарте (хотя есть некоторые правила, ниже), чтобы дать реализацию некоторую свободу в том, как провести их работу. Более формально, объекты этого типа имеют продолжительность жизни, которая должна длиться в течение всей программы ».

Объекты продолжительности статического хранения инициализируются в два этапа. Сначала выполняется «статическая инициализация», и только после выполнения всей статической инициализации выполняется «динамическая инициализация». При статической инициализации все объекты сначала инициализируются нулями; после этого все объекты с постоянной фазой инициализации инициализируются постоянным выражением (т.е. переменные инициализируются литералом или constexpr). Хотя это не указано в стандарте, фаза статической инициализации может быть завершена во время компиляции и сохранена в разделе исполняемого файла. Динамическая инициализация включает в себя всю инициализацию объекта, выполняемую с помощью конструктора или вызова функции (если функция не отмечена constexprв C ++ 11). Порядок динамической инициализации определяется как порядок объявления в модуле компиляции (то есть в том же файле). Не дается никаких гарантийных обязательств по инициализации между единицами компиляции.

Объекты продолжительности хранения потока

Переменные типа очень похожи на объекты статической продолжительности хранения. Основное отличие заключается в том, что время создания - непосредственно перед созданием потока, а выполняется после присоединения потока.

Объекты продолжительности автоматического хранения

Наиболее распространенными типами чисел в C ++ являются локальные переменные внутри функции или блока и временного периода. Общей чертой автоматических единиц является то, что у них есть время жизни, ограниченное областью действия. Они могут инициализировать точку объявления (подробности см. Ниже). Это реализуется путем вызова в стеке .

Локальные переменные последовательности, когда точка проходит точку объявления. Если переменная имеет конструктор или инициализатор, он используется для определения начального состояния объекта. Локальные переменные уничтожаются, когда закрывается локальный блок или функция, в которой они объявлены. Деструкторы C ++ для локальных переменных вызываются в конце жизненного цикла объекта, обеспечивая дисциплину автоматического управления ресурсами, называемую RAII, которая широко используется в C ++.

Переменные-члены создаются при создании родительского объекта. Члены массива инициализируются от 0 до последнего члена массива по порядку. Переменные-члены уничтожаются, когда родительский объект уничтожается в порядке, обратном созданию. т.е. если родительский объект является «автоматическим объектом», то он будет уничтожен, когда он выйдет за пределы области видимости, что вызовет уничтожение всех его членов.

Временные переменные создаются в результате оценки выражения и уничтожаются, когда оператор, содержащий выражение, был полностью вычислен (обычно в ;в конце оператора).

Объекты продолжительности динамического хранения

Эти объекты имеют динамический срок жизни и могут быть созданы напрямую с помощью вызова newи явно уничтожены с помощью вызова delete. C ++ также поддерживает mallocи freeиз C, но они несовместимы с newи delete. Использование newвозвращает адрес в выделенную память. Руководящие принципы C ++ Core не рекомендуют использовать newнепосредственно для создания динамических объектов в пользу интеллектуальных указателей через make_uniqueдля единоличного владения и make_sharedдля множественное владение с подсчетом ссылок, которое было введено в C ++ 11.

Шаблоны

Шаблоны C++ позволяют универсальное программирование. C ++ поддерживает шаблоны функций, классов, псевдонимов и чисел. Шаблоны могут быть параметризованы типами, константами времени компиляции и другими шаблонами. Шаблоны реализуются путем создания экземпляров во время компиляции. Чтобы создать экземпляр шаблона, компиляторы выполняют функцию шаблона, чтобы сгенерировать конкретную функцию или экземпляр класса. Некоторые невозможны замены; они устраняются политикой замены разрешения перегрузки, описываемой фразой «Ошибка не является ошибкой » (SFINAE). Шаблоны - это мощный инструмент, который можно использовать для универсального программирования, метапрограммирования шаблонов и оптимизации кода, но эта возможность требует затрат. Использование шаблона может увеличить размер кода, потому что каждый экземпляр создает копию шаблона шаблона: по одному для каждого набора аргументов шаблона, однако это такой же или меньший объем, который был бы сгенерирован, если бы код был написан вручную. Это контрастирует с дженериками времени выполнения представленными на других языках (например, Java ), где во время компиляции тип стирается, одно тело сохраняется.

Шаблоны отличаются от макросов : хотя обе эти языковые функции времени компиляции позволяют условную компиляцию, шаблоны не ограничиваются лексической заменой. Шаблоны осведомлены о семантике и типах своего сопутствующего языка, а также обо всех типах типов во время выполнения высокоуровневых операций, включая программное управление потоком на основе анализа параметров, строго проверенных по типу. Макросы способны выполнить компиляцию на основе предопределенных критериев, но не могут создать экземпляры новых типов, рекурсивно или выполнить тип и по сути, ограничиваются заменой текста перед компиляцией и включением / исключением текста. Другими словами, макросы могут управлять потоком компиляции на основе заранее определенных символов, но не могут, в отличие от шаблонов независимо создавать новые символы. Шаблоны - это инструмент для статического полиморфизма (см. Ниже) и общего программирования.

. Кроме того, шаблоны - это механизм времени компиляции в C ++, который является полным по Тьюрингу, что означает какое-либо вычисление, выраженное компьютерной программой, может быть вычислено в той или иной форме с помощью метапрограммы шаблона до времени выполнения.

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

Объекты

C ++ представляет функции объектно-ориентированного программирования (ООП) для C.Он предлагает классы, которые используются четыре функции, обычно присутствующие в ООП (и некоторые не-ООП) языки: абстракция, инкапсуляция, наследование и полиморфизм. Отличительной особенностью классов C ++ по сравнению с классами других языков программирования является поддержка детерминированных деструкторов , которые, в свою очередь, обеспечивают поддержку концепции Получение ресурсов - это инициализация (RAII).

Инкапсуляция

Инкапсуляция - это скрытие информации, чтобы устойчивые структуры и операторы использовались по назначению, и сделать модель использования более очевидной для разработчика. C ++ позволяет определять возможности определения и функции в качестве основных механизмов инкапсуляции. Внутри класса могут быть объявлены как общедоступные, защищенные или частные, чтобы явно обеспечить инкапсуляцию. Открытый член класса доступ любой функции. Закрытый член доступен только для функций, которые являются членами этого класса, а также для доступа к функциям и классам, явно предоставленным классом разрешения на доступ («друзья»). Защищенный член члена группы классов, которые наследуются от класса, в дополнение к самому классу и любым друзьям.

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

Обычно считается хорошей практикой сделать все данные частными или защищенными и сделать только общедоступными. те функции, которые являются частью минимального интерфейса для пользователей класса. Это может скрыть детали реализации данных, позволять разработать программу без какого-либо изменения интерфейса.

Наследование

Наследование позволяет одному типу данных приобретать свойства других данных. Наследование от базового класса может быть объявлено как общедоступное, защищенное или частное. Этот спецификатор доступа определяет, могут ли несвязанные и производные классы получить доступ к унаследованным общедоступным и защищенным базовым классом. Только публичное наследование соответствует тому, что обычно подразумевается под «наследованием». Две другие формы используются гораздо реже. Если спецификатор доступа опущен, «класс» наследуется частным образом, а «структура» - публично. Базовые классы могут быть объявлены виртуальными; это называется виртуальным наследованием. Виртуальное наследование гарантирует, что в графе наследования существует только один экземпляр базового класса, что позволяет избежать некоторых проблем неоднозначности множественного наследования.

Множественное наследование - это функция C ++, отсутствующая на большинстве других языков, позволяющая классу быть производным от более чем одного базового класса; это позволяет создать более сложные отношения наследования. Например, класс «Летающий кот» может наследовать как от «Кошка», так и от «Летающего млекопитающего». Некоторые другие языки, такие как C # или Java, выполнить нечто подобное (хотя и более ограниченное), разрешая наследование нескольких интерфейсов, ограничивая количество базовых классов до одного (интерфейсы, в отличие от классов, добавлены только объявления функций-членов, без реализации или данных-членов). Интерфейс, как в C # и Java, может быть определен в C ++, как класс, предоставляющий только чистые виртуальные функции, часто известный как абстрактный базовый класс или «ABC». Функции-члены такого абстрактного базового класса обычно явно в производном классе, а не наследуются неявно. Виртуальное наследование C ++ демонстрирует функцию разрешения неоднозначности, которая называется доминирование.

Операторы и перегрузка операторов

Операторы, которые не могут быть перегружены
ОператорСимвол
Оператор разрешения::
Условный оператор?:
оператор точки.
оператор выбора элемента.*
оператор "sizeof"sizeof
оператор "typeid"typeid

C ++ предоставляет более 35 операторов, охватывающих Базовую арифметику, манипуляции с битами, косвенное обращение, сравнение, логические операции и другие. Почти все операторы могут быть перегружены для некоторых заметных функций, как такие заметные члены (.и . *), а также условный оператор. Богатый набор перегружаемых операторов играет ключевую роль в том, чтобы пользовательские типы в C ++ выглядели как встроенные.

Перегружаемые операторы являются неотъемлемой частью многих передовых методов программирования на C ++, таких как интеллектуальные указатели. Перегрузка оператора не меняет приоритета вычислений с оператором, а также меняет количество операндов, которые использует оператор (однако любой операнд может игнорироваться оператором, хотя он будет оценен перед выполнением). Перегруженные операторы «» и «||»теряют свойство оценки короткого замыкания.

Полиморфизм

Полиморфизм позволяет использовать один общий интерфейс для многих реализаций, а объекты могут действовать по-разному в разных обстоятельствах.

C ++ поддерживает несколько видов статических (разрешенных во время компиляции ) и динамических (разрешенных во время времени выполнения ) полиморфизмов, поддерживаемых языковых особенности, описанные выше. Полиморфизм времени компиляции не позволяет принимать решения во время выполнения, в то время как полиморфизм времени выполнения обычно приводит к снижению производительности.

Статический полиморфизм

Перегрузка функций позволяет программам объявлять несколько функций с одинаковым именем, но разными аргументами (например, специальный полиморфизм ). Функции различаются или типом их формальных параметров. Таким образом, одно и то же имя функции может относиться к разным функциям в зависимости от контекста, в котором оно используется. Тип, возвращаемый функцией, не используется для сообщения о неисправности перегруженных функций и может привести к сообщению об ошибке времени компиляции.

При объявлении функций программист может указать для одного или нескольких параметров значение по умолчанию. Это позволяет опустить параметры со значениями по умолчанию при вызове функции, и в этом случае установка задания аргументы по умолчанию. Когда функция вызывается с меньшим указанным параметром, чем указано в параметрах, в списке параметров назначаются их аргументы по умолчанию. Во многих случаях указание аргументов по умолчанию в одном объявлении функции предпочтительнее.

Шаблоны в C ++ использовать сложный механизм для написания универсального полиморфного кода (например, параметрический полиморфизм ). В частности, с помощью необычного шаблона шаблона можно реализовать форму статического полиморфизма, которая точно имитирует синтаксис для переопределения виртуальных функций. Шаблоны C ++ распознают завершенные типы и по Тьюрингу, их также можно использовать, чтобы компилятору разрешать рекурсивные условные выражения и генерировать важные программы с помощью метапрограммирования шаблонов. Вопреки некоторому мнению, шаблон не будет генерировать массовый код после компиляции с правильными настройками компилятора.

Динамический полиморфизм

Наследование

Указатели числа и ссылки на базовый класс типа в C ++ также может ссылаться на объекты любых производных классов типа. Это позволяет классам и другим видам контейнеров содержать указатели на объекты разных типов (ссылки не могут храниться непосредственно в контейнерах). Это обеспечивает динамический (во время выполнения) полиморфизм, при помощи которого объекты могут вести себя по-разному, в зависимости от их (фактических, производных) типов.

C ++ также предоставляет оператор dynamic_cast, который позволяет коду безопасно преобразовать объект через базовую ссылку / указатель в более производный тип: понижающее преобразование. Попытка необходима, как часто неизвестно, на какой производный тип указан. (Апкастинг, преобразование в более общем типе, всегда можно проверить / выполнить во время компиляции с помощью static_cast, поскольку наследственные классы указаны в интерфейсе производного класса, видимого для всех вызывающих.) dynamic_castполагается на информацию о типах времени выполнения (RTTI), метаданные в программе, которые позволяют различать эти и их отношения. Если dynamic_castк указателю не удается, результатом является константа nullptr, тогда как, если адресатом является ссылка (которая не может быть нулевой), приведение вызывает исключение. Объекты, которые, как известно, принадлежат к определенному производному типу, могут быть преобразованы в него с помощью static_cast, минуя RTTI и безопасную проверку типов во время выполнения dynamic_cast, поэтому это следует использовать, только если программист очень уверен, что актерский состав действителен и всегда будет.

Виртуальные функции-члены

Обычно, когда функция в производном классе переопределяет функцию в базовом классе, функция для вызова определяется типом объекта. Данная функция переопределяется, если не существует разницы в количестве или типе параметров между двумя или более определениями этой функции. Следовательно, во время компиляции может оказаться невозможным определить тип объекта и, следовательно, правильную функцию для вызова, учитывая только указатель базового класса; поэтому решение откладывается до времени выполнения. Это называется динамической отправкой. Виртуальные функции-члены или методы позволяют вызывать наиболее конкретную реализацию функции в соответствии с фактическим типом времени выполнения объекта. В реализациях C ++ это обычно делается с помощью таблиц виртуальных функций. Если тип объекта известен, этого можно избежать, добавив перед вызовом функции полностью определенное имя класса , но в целом вызовы виртуальных функций разрешаются во время выполнения.

В дополнение к стандартным функциям-членам перегрузки операторов и деструкторы могут быть виртуальными. Как правило, если какая-либо функция в классе виртуальная, деструктор также должен быть. Поскольку тип объекта при его создании известен во время компиляции, конструкторы и конструкторы копирования расширений, не может быть виртуальным. Когда необходимо создать копию объекта, когда указатель на производный объект передается как указатель на производственный объект. В таком обычном случае создается копия производного класса при помощи clone ()(аналогичная).

Функцию-член также можно сделать «чистой», добавив к ней = 0после закрывающей круглой скобки и перед точкой с запятой. Класс, призную виртуальную функцию, называется абстрактным классом. Объекты нельзя создать из абстрактного класса; они могут быть получены только из. Любой производный класс наследует виртуальную функцию как чистую и все другие объекты производного класса. Программа, которая создает объект класса с чистой функцией-членом или унаследованной чистой функцией-членом, плохо сформирована.

Лямбда-выражения

C ++ обеспечивает поддержку анонимных функций, также как известные лямбда-выражения, в следующей форме:

[захват] (параметры) ->return_type {function_body}

Если лямбда не принимает параметры, () можно опустить, то есть

[захват] ->return_type {function_body}

Кроме того, тип возвращаемого значения лямбда-выражения может быть автоматически вывести, если возможно, например:

(int x, int y) {return x + y; } // выведено (int x, int y) ->int {return x + y; } // явный

Список [захват]поддерживает определение замыканий. Такие лямбда-выражения в стандарте как синтаксический сахар для безымянного объекта функции.

Обработка исключений

Обработка исключений используется для сообщений о существовании проблемы или во время ошибки выполнения. откуда она была обнаружена, где проблема может быть решена. Это позволяет делать это единообразно и отдельно от основного кода, обнаруживая при этом все ошибки. В случае возникновения ошибки возникает (вызывается) исключение, которое перехватывается ближайшим подходящим обработчиком. Исключение вызывается из каждой внешней области (распространения) для тех, пока не будет найден подходящий обработчик, вызывая, в свою очередь, деструкторы любых объектов в этих закрытых областях. В то же время исключение представляется как объект, данные об обнаруженной проблеме.

Некоторые руководства по стилю C ++, такие как Google, LLVM и Qt, запрещают использование исключений.

Код, вызывающий исключение, помещается внутри блока попробуйте. Исключения обрабатываются в отдельных блоках улов(обработчиках); каждый блок попробуйтеможет иметь несколько обработчиков исключений, как это видно в примере ниже.

1 #include 2 #include 3 #include 4 5 int main () {6 Попробуйте {7 std :: vector vec {3, 4, 3, 1}; 8 int i {vec.at (4)}; // Выдает исключение std :: out_of_range (индексирование для vec от 0 до 3, а не от 1 до 4) 9} 10 // Обработчик исключения перехватывает std :: out_of_range, который генерируется vec.at (4) 11 catch (std: : out_of_range e) {12 std :: cerr << "Accessing a non-existent element: " << e.what() << '\n'; 13 } 14 // To catch any other standard library exceptions (they derive from std::exception) 15 catch (std::exception e) { 16 std::cerr << "Exception thrown: " << e.what() << '\n'; 17 } 18 // Catch any unrecognised exceptions (i.e. those which don't derive from std::exception) 19 catch (...) { 20 std::cerr << "Some fatal error\n"; 21 } 22 }

Также можно целенаправленно вызвать исключение, используя слово throw; эти исключения обрабатываются обычным образом. В некоторых случаях исключение нельзя использовать по техническим причинам. Одним из таких примеров является критический компонент встроенной системы, где каждая операция должна быть гарантированно завершена в течение определенного периода времени. Это не может быть определено с исключениями, поскольку не существует инструментов для определения максимального времени, необходимого для обработки исключения.

В отличие от обработки сигналов, в котором функция обработки вызывается из точки В случае сбоя обработка исключений выходит из текущей области до того, как будет введен блок catch, который может находиться в текущей функции или любом из предыдущих вызовов функции, находящихся в настоящее время в стеке.

Стандартная библиотека

Проект стандарта «Рабочий документ», утвержденный как C ++ 98; половина его размера была посвящена стандартной библиотеке C ++

. Стандарт C ++ состоит из двух частей: основного языка и стандартной библиотеки. Программисты C ++ ожидают последнего от каждой крупной реализации C ++; он включает агрегированные типы (векторы, списки, карты, наборы, очереди, стеки, массивы, кортежи), алгоритмы (find, for_each, binary_search, random_shuffle и т. Д.), Средства ввода / вывода (iostream, для чтения и записи в консоль и файлы), библиотека файловой системы, поддержка локализации, интеллектуальные указатели для автоматическое управление памятью, поддержка регулярных выражений,, многопоточная библиотека, поддержка атомики (позволяющая считывать или записывать переменную не более чем одним потоком за раз без какой-либо внешней синхронизации), утилиты времени (измерение, получение текущего времени и т. д.), система для преобразования отчетов об ошибках, не использующая исключения C ++ в исключения C ++, генератор случайных чисел и слегка модифицированная версия стандартной библиотеки C (чтобы она соответствовала системе типов C ++).

Большая часть библиотеки C ++ основана на стандартной библиотеке шаблонов (STL). К полезным инструментам, предоставляемым STL, относятся контейнеры как коллекции объектов (например, векторы и списки ), итераторы, которые предоставляют массивы: например, доступ к контейнерам, и алгоритмы, которые выполняют такие операции, как поиск и сортировка.

Кроме того, предусмотрены (мульти) карты (ассоциативные массивы ) и (мульти) наборы, все из которых экспортируют совместимые интерфейсы. Следовательно, с помощью шаблонов можно писать общие алгоритмы, которые работают с любым контейнером или с любой последовательностью, определенной итераторами. Как и в C, к функциям из библиотеки можно получить доступ с помощью директивы #include для включения стандартного заголовка . Стандартная библиотека C ++ предоставляет 105 стандартных заголовков, 27 из которых являются устаревшими.

Стандарт включает STL, который был первоначально разработан Александром Степановым, который много лет экспериментировал с универсальными алгоритмами и контейнерами. Когда он начал с C ++, он наконец нашел язык, на котором можно было создавать общие алгоритмы (например, сортировку STL), которые работают даже лучше, чем, например, стандартная библиотека C qsort, благодаря таким функциям C ++, как использование встраивания и компиляции. привязка времени вместо указателей функций. Стандарт не называет его «STL», поскольку это просто часть стандартной библиотеки, но этот термин все еще широко используется, чтобы отличить его от остальной части стандартной библиотеки (потоки ввода / вывода, интернационализация, диагностика, подмножество библиотеки C и т. д.).

Большинство компиляторов C ++, и все основные из них, предоставляют соответствующую стандартам реализацию стандартной библиотеки C ++.

Основные принципы C ++

Основные рекомендации C ++ - это инициатива, возглавляемая Бьярном Страуструпом, изобретателем C ++, и Хербом Саттером, организатором и председателем рабочей группы C ++ ISO, для помощи программистам напишите «Современный C ++», используя лучшие практики для языковых стандартов C ++ 14 и новее, и помогите разработчикам компиляторов и инструментов статической проверки создавать правила для выявления плохих практик программирования.

Основная цель состоит в том, чтобы эффективно и последовательно писать на C ++ с безопасным типом и ресурсами.

Основные принципы были объявлены во вступительной речи на CPPCon 2015.

Руководящие принципы сопровождаются библиотекой поддержки рекомендаций (GSL), библиотекой типов и функций только для заголовков для реализации ядра. Руководства и инструменты статической проверки для обеспечения соблюдения правил Руководства.

Совместимость

Чтобы предоставить поставщикам компиляторов большую свободу, комитет по стандартам C ++ решил не диктовать реализацию изменения имен, обработка исключений и другие особенности реализации. Обратной стороной этого решения является то, что объектный код, созданный разными компиляторами, будет несовместим. Однако были попытки стандартизировать компиляторы для конкретных машин или операционных систем (например, C ++ ABI), хотя сейчас от них, похоже, в значительной степени отказались.

С C

C ++ часто рассматривается как надмножество C, но это не совсем так. Большую часть кода C можно легко заставить правильно скомпилировать в C ++, но есть несколько отличий, из-за которых некоторый допустимый код C становится недопустимым или ведет себя иначе в C ++. Например, C допускает неявное преобразование из void *в другие типы указателей, а C ++ - нет (по соображениям безопасности типов). Кроме того, C ++ определяет множество новых ключевых слов, таких как newи class, которые могут использоваться в качестве идентификаторов (например, имен переменных) в программе на языке C.

Некоторые несовместимости были устранены в версии 1999 года стандарта C (C99 ), который теперь поддерживает функции C ++, такие как строковые комментарии (//) и объявления смешанный с кодом. С другой стороны, C99 представил ряд новых функций, которые C ++ не поддерживал и которые были несовместимы или избыточны в C ++, такие как массивы переменной длины, собственные типы комплексных чисел (однако Класс std :: complexв стандартной библиотеке C ++ обеспечивает аналогичную функциональность, хотя и не совместим с кодом), назначенные инициализаторы, составные литералы и ключевое слово restrict. Некоторые из представленных в C99 функций были включены в следующую версию стандарта C ++, C ++ 11 (из тех, которые не были избыточными). Однако стандарт C ++ 11 вводит новые несовместимости, такие как запрет на присвоение строкового литерала символьному указателю, который остается действительным C.

Чтобы смешивать код C и C ++, любое объявление или определение функции, которое является для вызова / использования как в C, так и в C ++, необходимо объявить со связью C, поместив ее в блок extern "C" {/*...*/}. Такая функция может не полагаться на функции, зависящие от изменения имени (т. Е. Перегрузки функции).

Критика

Несмотря на широкое распространение, некоторые известные программисты критиковали язык C ++, в том числе Линус Торвальдс, Ричард Столлман, Джошуа Блох, Кен Томпсон и Дональд Кнут.

Один из наиболее часто критикуемых моментов C ++ - его воспринимаемая сложность как языка, с критикой того, что большое количество не- Ортогональные функции на практике требуют ограничения кода подмножеством C ++, таким образом избегая преимуществ читабельности общего стиля и идиом. Как выразился Джошуа Блох :

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

Дональд Кнут (1993, комментирует предварительно стандартизованный C ++), который сказал о Эдсгере Дейкстре, что «мысль о программировании на C ++» «сделает его физически больным»:

Проблема, с которой я столкнулся сегодня с ними, заключается в том, что... C ++ слишком сложен. На данный момент для меня невозможно написать переносимый код, который, как я считаю, работал бы на множестве разных систем, если я не избегаю всех экзотических функций. Всякий раз, когда у разработчиков языка C ++ возникали две конкурирующие идеи относительно того, как им решать какую-либо проблему, они говорили: «Хорошо, мы сделаем их обе». Так что язык на мой вкус слишком барочный.

Кен Томпсон, который был коллегой Страуструпа в Bell Labs, дает свою оценку:

В этом, безусловно, есть свои плюсы. Но в целом я считаю, что это плохой язык. Он делает многое наполовину хорошо, и это просто куча взаимоисключающих идей. Все, кого я знаю, будь то личные или корпоративные, выбирают подмножество, и эти подмножества разные. Так что это не лучший язык для переноса алгоритма - сказать: «Я написал его; вот, возьми. Он слишком большой, слишком сложный. И очевидно, что построен комитетом. Страуструп годами, годами и годами проводил кампанию, выходящую за рамки любого технического вклада, который он внес в язык, за его принятие и использование. И он вроде как руководил всеми комитетами по стандартам с помощью кнута и стула. И он никому не сказал «нет». Он вложил все функции на этом языке, которые когда-либо существовали. Это не было чисто разработано - это был просто союз всего, что происходило. И я думаю, что он сильно пострадал от этого.

Однако Брайан Керниган, также коллега в Bell Labs, оспаривает эту оценку:

C ++ оказал огромное влияние.... Многие люди говорят, что C ++ слишком велик, слишком сложен и т. Д. И т. Д., Но на самом деле это очень мощный язык, и почти все, что там есть, существует по действительно веской причине: это не кто-то случайные изобретения, на самом деле это люди, пытающиеся решить проблемы реального мира. Многие программы, которые мы сегодня принимаем как должное и которые мы просто используем, являются программами на C ++.

Сам Страуструп отмечает, что семантика C ++ намного чище, чем его синтаксис: «внутри C ++ есть гораздо меньший и более чистый язык, изо всех сил пытающийся выйти».

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

См. также

  • icon Компьютер портал программирования

Ссылки

Дополнительная литература

Внешние ссылки

  • JTC1 / SC22 / WG21 - рабочая группа ISO / IEC по стандарту C ++
  • Standard C ++ Foundation - некоммерческая организация, которая способствует использованию и пониманию стандарта C ++. Бьярн Страуструп - директор организации.
Последняя правка сделана 2021-05-13 08:52:40
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте