Найти в Дзене
Разработчик (up)

С++? Что из себя представляет?

C++ (Си-плюс-плюс) — язык программирования общего назначения с поддержкой нескольких парадигм программирования: объектно-ориентированной, обобщенной, процедурной и др. Б'ярн Страуструп (англ. Bjarne Stroustrup) начал создавать C++ в AT&T Bell Laboratories (Мюррей-Хилл[en], Нью-Джерси) в 1979 году. На этапе зарождения речь имела название «Си с классами». Впоследствии Страуструп переименовал язык C++ в 1984г. Берет истоки из языка программирования С. Впервые описана международным стандартом ISO/IEC 14882:1998 (C++98), наиболее актуальным является стандарт ISO/IEC 14882:2020 (C++20). В 1990-х годах C++ стала одной из наиболее часто используемых языков программирования общего назначения. Язык используют для системного программирования, разработки прикладного программного обеспечения, написания драйверов, мощных серверных и клиентских приложений, а также для разработки развлекательных программ, например, видеоигр. C++ существенно повлияла на другие популярные сегодня языки программирования:
Оглавление

C++ (Си-плюс-плюс) — язык программирования общего назначения с поддержкой нескольких парадигм программирования: объектно-ориентированной, обобщенной, процедурной и др. Б'ярн Страуструп (англ. Bjarne Stroustrup) начал создавать C++ в AT&T Bell Laboratories (Мюррей-Хилл[en], Нью-Джерси) в 1979 году. На этапе зарождения речь имела название «Си с классами». Впоследствии Страуструп переименовал язык C++ в 1984г. Берет истоки из языка программирования С. Впервые описана международным стандартом ISO/IEC 14882:1998 (C++98), наиболее актуальным является стандарт ISO/IEC 14882:2020 (C++20).

В 1990-х годах C++ стала одной из наиболее часто используемых языков программирования общего назначения. Язык используют для системного программирования, разработки прикладного программного обеспечения, написания драйверов, мощных серверных и клиентских приложений, а также для разработки развлекательных программ, например, видеоигр. C++ существенно повлияла на другие популярные сегодня языки программирования: C# и Java.

JAVA

C#

История

Хронология

-2

Б*ярн Страуструп, создатель языка

История развития языка программирования С++ содержит такие ключевые события:

  • апрель 1979 — начало работы над Ci с классами (C with Classes)
  • октябрь 1979 — рабочая версия Ci с классами (с CPre компилятором)
  • август 1983 — Ci с классами впервые используется в Bell Labs
  • 1984 — название C++
  • февраль 1985 — первый внешний выпуск компилятора C++ — Cfront Relese E (Educational — выпуск для учебных заведений)
  • октябрь 1985 — первый коммерческий выпуск — Cfront 1.0
  • февраль 1987 — Cfront 1.2
  • декабрь 1987 года — первый выпуск GNU C++ (1.13)
  • 1988 — Первые выпуски Oregon Software C++ Zortech C++
  • июнь 1989 — Cfront 2.0
  • 1989 — книга «The Annotated C++ Reference Manual» (ARM); Учрежден комитет ANSI C++
  • 1990 — первая техническая встреча комитета ANSI C++; принято шаблоны (templates), исключительные ситуации (exceptions); первый выпуск Borland C++
  • 1991 — Первая встреча комитета ISO/IEC; Cfront 3.0 (с шаблонами); книга «The C++ Programming Language» (2-я редакция)
  • 1992 — Первые выпуски IBM, DEC, Microsoft C++
  • 1993 — RTTI (Run-time type identification — определение типа во время выполнения) принято; пространства имен (namespaces) и string (шаблонный с символьным типом) принято
  • 1994 — принято STL
  • 1997 — окончательное голосование комитета за завершенный стандарт
  • 1998 — ратифицирован стандарт ISO/IEC 14882:1998 C++ (так называемый C++98)
  • 2003 — ратифицирован стандарт ISO/IEC 14882:2003 C++ (так называемый C++03); начало работы над C++0x

Дальнейшее развитие описан в статьях о соответствующих версии С++.

История названия

Название «Си++» было придумано Риком Масситти (Rick Mascitti) и впервые было использовано в декабре 1983 года. Ранее, на этапе разработки, новый язык назывался «Си с классами». Имя, что получилось в итоге, происходит от оператора Си++» (увеличение значения переменной на единицу) и распространенного способа присвоения новых имен компьютерным программам, заключается в добавлении к имени символа «+» для обозначения улучшений. В соответствии со Страуструпом, «это название указывает на эволюционную природу изменений Ci». Выражением «С+» называли утреннюю, не связанную с Си++, язык программирования.

Некоторые программисты на Си могут отметить, что если выполняются выражения x=3; y=x++; то в результате получится x=4 и y=3, потому что x увеличивается только после присоения его. Однако если второе выражение будет y=++x; то получится x=4 и y=4. Исходя из этого, можно сделать вывод, что логичнее было бы назвать язык не Си++, а в Си++. Однако оба выражения c++ и c ++увеличивают с, а кроме того выражение c++ распространеннее.

Педанты могут отметить, что введение языка Си++ не меняет самого Си, поэтому самым точным именем было бы «С+1».

eos.shadrkvant.ru
eos.shadrkvant.ru

Стандарт C++11

Подробнее: C++11

В августе 2011 года завершилась длительная эпопея с принятием нового стандарта для языка Си++. Комитет ISO по стандартизации C++ единогласно утвердил спецификацию C++0X как международный стандарт C++11». Стандарт C++0X планировалось выпустить еще в 2008 году, но его принятие постоянно откладывалось. Большинство представленных в стандарте возможностей уже поддерживаются в таких компиляторах, как GCC, IBM C++, Intel C++ и Visual C++. Поддерживающие C++11 стандартные библиотеки реализованы в рамках проекта Boost.

Новый стандарт развивался более 10 лет и пришел на смену стандартам C++98 и C++03. Отмечается, что если различия между стандартами C++98 и C++03 были настолько незначительными, что их можно было не заметить, то стандарт C++11 содержит ряд кардинальных улучшений, как самого языка, так и стандартной библиотеки. По словам Б'ярна Страуструпа, создателя C++, C++11 чувствуется как новый язык, части которой лучше сочетаются друг с другом. В C++11 высокоуровневый стиль программирования стал более естественным. Кроме того, речь стала проще для изучения.

Стандарт C++14

Подробнее: C++14

Полное название: «International Standard ISO/IEC 14882:2014(E) Programming Language C++». C++14 можно рассматривать как небольшое расширение для C++11, который в основном содержит исправления ошибок и незначительные улучшения.

Комитет по разработке нового стандарта опубликовал черновик N3690 15 мая 2013. Рабочий вариант черновики N3936 был опубликован 2 марта 2014 года, финальный период голосования закрыт 15 августа 2014 года, а результат (единогласное одобрение) объявлен 18 августа 2014 года. Дата официального выпуска C++14 — 15 декабря 2014.

Поскольку разработка стандарта была достаточно длительной, и не было определено года выпуска, в период разработки также имел распространенное название «C++1y», аналогично тому, как стандарт C++11 до выпуска называли «C++0x»(выпуск этой версии ожидали до 2010 года).

Описанные ниже возможности языка соответствуют черновике N3797. Они могут отличаться от окончательной версии стандарта.

Стандарт C++17

Подробнее: C++17

Стандарт C++17 пришел к черновой версии стандарта в марте 2017 года и был окончательно утверждена 8 сентября 2017 года. Стандарт официально опубликован в декабре 2017

В С++17 был внесен ряд изменений в речь, в частности, добавлено несколько новых библиотек(<string_view>, <execution>), алгоритмов(std::exclusive_scan, std::for_each) и классов в STL, улучшена работа с лямбда-выражениями, обновлено библиотеку <thread> для мультипотокового программирования.

Стандарт C++20

Подробнее: C++20

Стандарт C++20 утвержден 4 сентября 2020 года. Стандарт официально опубликован в декабре 2020. Эта версия имеет гораздо больше нововведений по сравнению с C++14 и C++17.

В частности, эта версия вводит «концепции», сопрограммы, новый оператор сравнения <=>, прочее.

Особенности

При создании C++ стремились сохранить совместимость с языком С. Большинство программ на С исправно работать и с компилятором С++. С++ имеет синтаксис, основанный на синтаксисе С (см. список операторов языков С и С++).

Нововведениями С++ в сравнении с C являются:

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

Новые возможности в сравнении с С

Язык Си++ во многом являющееся расширением набора Сек. Новые возможности C++ включают объявления в виде выражений, преобразования типов в виде функций, операторы new и delete, тип bool, ссылки, расширенное понятие константности и сменности, функции, подставляются, аргументы по умолчанию, переопределения, пространства имен, классы (включая и все связанные с классами возможности, такие как наследование, функции-члены (методы), виртуальные функции, абстрактные классы и конструкторы), переопределения операторов, шаблоны, оператор ::, обработку исключений, динамическую идентификацию и многое другое. Си++ является также языком строгого типирования и налагает больше требований по соблюдению типов, по сравнению с Си.

В С++ появились комментарии в виде двойной косой черты («//»), которые были в предшественнике C — языке BCPL.

Некоторые особенности C++ позднее были перенесены в C, например, ключевые слова const и inline, объявления в циклах for и комментарии в стиле С++ («//»). В более поздних реализациях C также были представлены возможности, которых нет в С++, например макросы vararg и улучшенная работа с массивами-параметрами.

Объектно-ориентированные особенности языка

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

Проблемы старого подхода

В языке C основным способом организации данных были структуры. Структура состоит из набора полей, которые никак не защищены. Если элементы структуры имеют переменную длину, их представляют в виде указателей. Выделение и освобождение памяти под эти указатели делаются вручную. Так, например, одномерный массив переменной длины в языке C с проверкой границ может представляться следующим образом:

struct Array { double* val; int len; };
void FreeArray (
const struct Array*); void AllocArray (const struct Array*, int len); double Elem (const struct Array*, int i); void ChangeElem (const struct Array*, int i, double x);

Такая реализация опасна и неэффективна по многим причинам:

  • Необходимо вызвать FreeArray и AllocArray. Программист может забыть вызвать одну из этих функций, или вызвать ее очень рано/поздно, или дважды, или по указателю на неправильный массив. Все это приводит к ошибкам, которые трудно обнаружить.
  • Функции Elem и ChangeElem медленные.
  • Нет никакого способа помешать программистам создавать и другие функции для работы со структурой Array. Эти функции могут делать с полями и val len угодно.
  • Нет никакого способа помешать программистам непосредственно менять поля len и val.
  • Присвоение объектов типа struct Array приведет к тому, что их поля val будут указывать на одну и ту же область памяти. Нет никакого способа ни запретить присвоение, ни изменить такое поведение.

Язык С++, используя ООП, устраняет все эти проблемы.

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

Основным способом организации информации в C++ являются классы. В отличие от типа, структура (struct) языка C, которая состоит только из полей, класс (class) C++ состоит из полей и функций-членов или методов (англ. member functions). Поля бывают публичными (public), защищенными (protected) и приватными (private). В С++ тип структура аналогичного типа класс, отличие в том, что по умолчанию поля и функции-члены у структуры публичные, а у класса — приватные.

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

Используя инкапсуляцию, автор класса может защитить свои данные от некорректного использования. Кроме того, она задумывалась для облегчения совместной разработки классов. Имелось в виду, что изменение способа хранения данных, если они объявлены как защищенные или частные, не требует соответствующих изменений в классах, которые используют изменен класс. Например, если в старой версии класса данные хранились в виде линейного списка, а в новой версии — в виде дерева, те классы, которые были написаны до изменения формата хранения данных, переписывать не потребуется, если данные были частными или защищенными (в последнем случае — если используя классы не были классами-потомками), поскольку ни один из них этих классов не мог бы напрямую обращаться к данным, а только через стандартные функции, которые в новой версии имеют уже корректно работать с новым форматом данных. Даже оператор доступа operator [] может быть определен как такая стандартная функция.

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

Используя инкапсуляцию, Array структуру из предыдущего раздела можно переписать таким образом:

class Array { public: void Alloc(int new_len); void Free(); inline double Elem(int i); inline void ChangeElem(int i, double x); protected: int len; double* val; };
void Array::Alloc(int new_len) {
if (len>0) Free(); len=new_len; val=new double[new_len];} void Array::Free() {delete [] val; len=0;} inline double Array::Elem(int i) {assert(i>=0 && i<len ); return val[i];} inline void Array::ChangeElem(int i, double x) {assert(i>=0 && i<len); val[i]=x;}

И далее

Array a; a.Alloc(10); a.ChangeElem(3, 2.78); double b = a.Elem(3); a.Free();

Здесь массив А имеет 4 публичных функции-члена и 2 защищенных поля. Описатель inline означает, что вместо вызова функции ее код подставляется в точку вызова, что решает проблему неэффективности.

juststartcoding.wordpress.com
juststartcoding.wordpress.com

Преимущества и недостатки

Преимущества языка C++

  • Стандартизация. C++ определяется международным стандартом а следовательно не контролируется какой-то одной фирмой или человеком.
  • Быстродействие. Скорость работы программ на С++ практически не уступает программам на С, хотя программисты получили в свои руки новые возможности и новые средства.
  • Эффективность. Решения разработаны на С++ могут использовать минимально необходимое количество ресурсов таких как память, ЦПУ, энергия и другие.
  • Масштабируемость. На языке C++ разрабатывают программы для самых различных платформ и систем, которые варьируются по размеру от нескольких до миллионов строк кода.
  • Возможность работы на низком уровне с памятью, адресами, портами. (Что, при неосторожном использовании, может легко превратиться в недостаток.)
  • Возможность создания обобщенных алгоритмов для разных типов данных, их специализация, и вычисления на этапе компиляции с использованием шаблонов.
  • Поддерживаются различные стили и технологии программирования, включая традиционное процедурное программирование, ООП, обобщенное программирование, метапрограммирование (шаблоны, макросы).

Недостатки языка C++

  • Наличие множество возможностей, которые нарушают принципы типобезпеки приводит к тому, что в С++ программы может легко закрасться важковловима ошибка. Вместо контроля со стороны компилятора разработчики вынуждены придерживаться весьма нетривиальных правил кодирования. По сути, эти правила ограничивают С++ рамками какой более безопасной підмови. Большинство проблем типобезпеки С++ унаследованная от С, но важную роль в этом вопросе играет и отказ автора языка от идеи использовать автоматическое управление памятью (например, сборку мусора). Так визитной карточкой С++ стали уязвимости типа «переполнение буфера».
  • Плохая поддержка модульности. Подключение интерфейса внешнего модуля через препроцесорную вставку заглавного файла (include) серьезно замедляет компиляцию, при подключении большого количества модулей. Для устранения этого недостатка, многие компиляторы реализуют механизм прекомпіляції заголовочных файлов.
  • Недостаток информации о типах данных во время компиляции (CTTI).
  • Язык C++ является сложным для изучения и для компиляции.
  • Некоторые преобразования типов неінтуїтивні. В частности, операция над беззнаковым и знаковым числами выдает беззнаковый результат.
  • Препроцессор С++ (унаследованный от C) очень примитивен. Это приводит с одной стороны к тому, что с его помощью нельзя (или тяжело) осуществлять некоторые задачи метапрограммирование, а с другой, вследствие своей примитивности, он часто приводит к ошибкам и требует много действий по обходу потенциальных проблем. Некоторые языки программирования (например, Scheme и Nemerle) имеют намного более мощные и более безопасные системы метапрограммирование (также называемые макросами, но макросы С/С++ они мало напоминают).
  • С конца 1990-х в сообществе С++ получило распространение так называемое метапрограммирование на основе шаблонов. По сути, оно использует особенности шаблонов C++ в целях реализации на их базе интерпретатора примитивного функционального языка программирования, который выполняется во время компиляции. Сама по себе данная возможность весьма привлекательна, но, вследствие вышеупомянутого, такой код весьма трудно воспринимать. Языки Lisp/Scheme, Nemerle и некоторые другие имеют более мощные и одновременно более простые для восприятия подсистемы метапрограммирование. Кроме того, в языке D реализована сравнимая по мощности, но значительно более простая в применении подсистема шаблонного метапрограммирование.
  • Хотя декларируется, что С++ мультипарадигмена язык, реально в языке отсутствует поддержка функционального программирования. Отчасти, данный пробел устраняется различными библиотеками (Loki, Boost) использующими средства метапрограммирование для расширения языка функциональными конструкциями (например, поддержкой лямбд/анонимных методов), но качество подобных решений значительно уступает качеству встроенных в функциональные языки решений. Такие возможности функциональных языков, как сопоставление с образцом, вообще крайне сложно эмулировать средствами метапрограммирование.

Критика языка C++

C++ унаследовала много проблем языка C:

  • Операция присваивания обозначается как =, а операция сравнения как == . Их легко спутать, и такая конструкция будет синтаксически правильным, но приведет к важковломимого багу. Особенно часто это происходит в операторах if и while, например, программист может написать if (i=0) вместо if (i==0) (Вместе с тем, основная масса компиляторов выдает в таких случаях предупреждения.) Избежать ошибку такого типа можно, если писать все операции сравнения в таком виде: if (0==i). К тому же много языков (Бейсик, Паскаль) используют символ "=" именно в операциях сравнения.
  • Операции присваивания (=), інкрементації (++), декрементації (--) и другие возвращают значение. В сочетании с обилием операций это позволяет, но не обязывает, программиста создавать код, который трудно читается. С другой стороны, один из основных принципов языков C и C++ — позволять программисту писать в любом стиле, а не навязывать «хороший» стиль. К тому же это иногда позволяет компилятору создавать более оптимальный код.
  • Макросы (define) являются мощным, но опасным средством. В языке C++, в отличие от C, необходимость в опасных макросах появляется значительно реже благодаря шаблонам и встроенным функциям. Но в унаследованных стандартных С-библиотеках много потенциально опасных макросов.

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

Сравнение C++ с языками Java и C#

Язык С++ с появлением первых трансляторов нашла сразу же очень широкое распространение, на нем было создано огромное количество программ и приложений. По мере накопления опыта создания больших программных систем всплыли недостатки, которые побудили к поиску альтернативных решений. Таким альтернативным решением стал язык Java, которая в некоторых отраслях стала конкурировать в популярности с C++, а фирма Microsoft предложила язык C# как новый язык, что развивает принципы C++ и использует преимущества языка Java. В дальнейшем появилась язык Nemerle объединяет преимущества C# с возможностью функционального программирования. В последнее время появилась попытка объединения эффективности C++, безопасности и скорости разработки, как в Java и C# — была предложена язык D, которая пока не получила широкого признания.

Язык Java имеет такие особенности, которых нет в языке C++ :

  • Java является типобезпечною языке. Типобезпека гарантирует отсутствие в программах ошибок, которые трудно найти и которые связаны с неправильной интерпретацией памяти компьютера. Это делает процесс разработки более надежным и предсказуемым, а значит быстрее. Так же это позволяет привлекать к разработке программистов, которые имеют меньшую квалификацию и иметь крупные группы разработчиков.
  • Java-код сначала компилируется не в машинный код, а в некоторый промежуточный код, который в дальнейшем интерпретируется или компилируется, тогда как многие C++ компиляторов ориентированы на компиляцию в машинный код заданной платформы.
  • В языке Java есть четко определенные стандарты на ввод-вывод, графику, геометрию, диалог, доступ к базам данных и других типичных применений. Благодаря этим особенностям, приложения на Java имеют значительно лучшую кросплатформнность, чем С++, и часто, будучи написаны для определенного компьютера и операционной системы, работают под другими системами без изменений. Программисты пишут на языке Java, не зависят от пакетов, навязанных разработчиками компиляторов на данное конкретное среду, что резко упрощает портирование программ.
  • В языке Java реализовано полноценное сбора мусора, которого нет в C++. Нет в С++ и средств проверки правильности указателей. С другой стороны, C++ обладает набором средств (конструкторы и деструкторы, стандартные шаблоны, ссылки), позволяющих почти полностью исключить выделение и освобождение памяти вручную и опасные операции с указателями. Однако такое исключение требует определенной культуры программирования, тогда как в языке Java оно реализуется автоматически.
  • Язык Java является чисто объектно-ориентированным, тогда как C++ поддерживает как объектно-ориентированное, так и процедурное программирование.
  • В C++ отсутствует полноценная информация о типах во время выполнения ( RTTI. Эту возможность можно было бы реализовать в C++, имея полную информацию о типах во время компиляции CTTI.
  • В C++ есть возможность ввода пользовательского синтаксиса с помощью define, что может привести к тому, что модули в больших пакетах программ становятся сильно связаны друг с другом. Это резко снижает надежность пакетов и возможность организации разделенных модулей. С другой стороны, С++ предоставляет достаточно средств (константы, шаблоны, встроенные функции) для того, чтобы практически полностью исключить использование define.

Эти отличия приводят к ожесточенным спорам между сторонниками двух языков о том, какой язык лучше. Сторонники Java считают эти особенности преимуществами; сторонники C++ считают, что во многих случаях эти особенности являются недостатками

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

Далеко не все программисты являются сторонниками одного из языков. По мнению некоторых программистов, Java и C++ не являются конкурентами, потому что имеют разные области применения. Другие считают, что выбор языка для многих задач является вопросом личного вкуса. Некоторые архитекторы программных решений базируют свой выбор языка программирования для того или иного решения на основе сильных и слабых сторон языков программирования так общем контексте разработки решения.