Продолжающееся путешествие от C к современному C++

Задний план:

Я инженер-программист. Хотя недавно переделал. Я получил двойную Е с несовершеннолетним в CS. Работал инженером-нефтяником. Пока я не понял, что мне действительно нравится заниматься программированием. Итак, я переключился.

Я знал C++ по университетской работе. Я изучил Java-программирование для Android-приложений. Для развлечения в качестве подработки. Я выучил Python, чтобы возиться с Raspberry Pi и пробиться в индустрию обработки данных. Тем не менее, для работы я должен был сделать C. Как это может быть сложно, подумал я. Ну, очень похоже на C++, которому меня учили в школе. Тем не менее, он сильно отличается от современных языков высокого уровня, которые я выучил позже. Что без занятий! Нет перегрузки функций! Никаких простых в использовании функций для работы со строками! Запомнить! Сюрпризы закончились не скоро.

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

Итак, я решил выйти за рамки C и погрузиться в мир современного C++. Медленно-медленно интегрируем больше C++ в исходную базу. Я могу создавать код C с помощью компиляторов C++. Итак, я решил вести журнал. Вещи, которые я открываю по пути. Я был бы признателен, если бы другие (более опытные) программисты указали на ошибки в этой статье и дополнили ее. Вот так.

Основы:

  • Инициализатор {}:
    В C нельзя использовать {} для инициализации значения без =, который вызывает копию:

Итак, почему, еще отличается? {} выполняет проверку типов во время компиляции. Следующее не будет компилироваться:

Установка i на 0,1 в C вызовет предупреждение.

  • Ключевое слово auto:
    В C++ можно использовать auto. auto избавляет от необходимости понимать, что возвращает функция. Поначалу для программиста, предвзято относящегося к типам, это звучало не очень умно. Тем не менее, при работе с объектами в разных пространствах имен использование auto делает код чище и удобнее в сопровождении по мере изменения API.
  • for in :
    Это одно из моих любимых. Сочетание этого с auto упрощает итерацию по итерации. Не говоря уже о аккуратности. Поскольку большинство итераций обычно происходит по всей коллекции, это становится очень удобным.
  • Ссылка и в объявлении:
    Ссылки, с точки зрения программиста C, представляют собой константный указатель, который передается и отслеживается за сценой. Возьмем следующий пример:

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

(Игнорируйте тот факт, что это будет преобразовано в число с плавающей запятой, а затем обратно в целое число)

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

  • nullptr & NULL:
    nullptr заменяет собой использование NULL. NULL обычно определяется в C как 0. Использование языковой константы, такой как nullptr, устраняет путаницу. Присвоение указателю нуля по-прежнему разрешено в C++, но не одобряется.
  • Пространства имен
    Пространства имен — очень интересный инструмент, помогающий уточнить наименования объектов. В пространстве имен один раз можно сгруппировать несколько связанных объектов в пространстве имен. Следовательно, эти имена можно повторно использовать в другом месте, либо в другом пространстве имен, либо в глобальном пространстве имен.
    Как только объект находится в пространстве имен, на него можно ссылаться, используя синтаксис namespace::object
    Импорт имени из определенного пространства имен (т. е. использование его без прикрепленного к нему пространства имен) может быть достигается с помощью «использования». Импорт всех имен пространств имен в глобальное пространство имен можно выполнить с помощью «using namespace::»
  • классы-перечисления
    C поддерживает типы-перечисления. Тем не менее, перечисляемые классы — это новое дополнение к языку C++, которое (по аналогии с пространством имен) содержит термины перечисления в своем собственном пространстве. В C это не скомпилируется

Использование классов инкапсулирует каждое перечисление, но доступ к термину перечисления требует использования имени класса, чтобы компилятор мог различать их.

  • обработка ошибок
    C++ имеет встроенные функции для обработки исключений. Язык предоставляет способы обнаружения неожиданного или ошибочного поведения, которого нельзя ожидать (аппаратный сбой, ошибка ОС и т. д.). Можно также «подбросить» исключение вверх по стеку, чтобы другой объект мог с ним справиться. Эмуляция того же поведения в C — ручная работа, нестандартизированная и синтаксически непонятная.
  • Приведение
    Приведение в C немного неоднозначно. Приведение переменной может преобразовать ее тип. Преобразование ячейки памяти просто изменит интерпретацию системы и обработку значения в этой ячейке.
    С другой стороны, C++ содержит несколько типов мощных возможностей приведения для управления преобразованием типов. Основные методы приведения: static_cast, dynamic_cast, reinterpret_cast, const_cast. Dynamic Cast идеально подходит для использования между указателями и ссылками на классы. Это добавляет дополнительную проверку, чтобы убедиться, что преобразование является допустимым. С другой стороны, статические приведения не выполняют проверки преобразования. Преобразования Reinterpret выполняют преобразование двоичного уровня из одного типа в другой. Наконец, const_cast меняет тип с константного на неконстантный или наоборот.
  • Союзы
    Функционально союзы остаются прежними. Тем не менее, в C++ последний использованный тип называется активным членом, и он является единственным действительным членом до следующего присваивания. Другими словами, присвоение значения определенного типа члена элементу объединения, а затем доступ к элементу с использованием другого типа члена считается поведением undefined. Я бы подумал, что это неразумно делать даже в C.
    Рассмотрите возможность использования Variant из стандартной библиотеки C++.
  • Структуры (как классы)
    C++ позволяет структурам содержать функции. Это полезная функция для классов, которые содержат все открытые члены (переменные и функции). Структура может до некоторой степени действовать как класс.
  • Классы и объектно-ориентированные функции
    C на самом деле не поддерживает классы, наследование и полиморфизм. Есть способы эмулировать подобное поведение в C, но это уже совсем другой пост.
  • Перегрузка функций:
    В языке C разрешен один прототип функции (в старых определениях языка C функцию можно определить только по ее возвращаемому типу). Что касается C++, одно и то же имя функции может использоваться для разных прототипов функций.

Это не разрешено в C. Тем не менее, в C++

это совершенно нормально (пока компилятор может сделать вывод, какой из них вы вызываете).

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

Не стесняйтесь обращаться ко мне по поводу изменений или дополнений к этому сообщению.

Использованная литература:





Путешествие по C++
В книге «Путешествие по C++, второе издание
Бьярн Страуструп, создатель языка C++, описывает, что представляет собой современный язык C++. Это…learning.oreilly.com»



https://stackoverflow.com/questions/10586003/try-catch-statements-in-c