Основное различие, о котором я могу думать, состоит в том, что C ++ является гораздо большим языком мультипарадигмы, чем C и C #. В C # ООП по-прежнему парадигма . Это язык ООП прежде всего, и если вы не используете ООП, сообщество C # скажет вам, что вы делаете это неправильно.
(хотя в C # в последние несколько лет добавлена довольно хорошая поддержка и для нескольких функциональных программ).
В C ++ ООП, ну, в общем, поддерживается, и вы можете использовать его, когда захотите, но вся суета связана с общим программированием. Шаблоны C ++ допускают широкий спектр умных, многократно используемых и универсальных библиотек и достигают многих из тех же целей, что и старомодные ООП, но без больших иерархий наследования и практически без связи между классами. Стандартная библиотека содержит много примеров этого
В C ++, многие конструкции C, хотя и остаются допустимыми, в основном избегают:
- Необработанные указатели ( обычно заменяются интеллектуальными указателями, такими как
boost::shared_ptr
или std::auto_ptr
, или ссылками
- Распределение памяти в пользовательском коде (обычно должно быть заключено в умный указатель или в специальный объект RAII)
- Функциональные указатели (обычно заменяются функторами, для лучшей безопасности типов и производительности)
- goto (Часто используется в C для перехода к коду очистки. Опять же, ненужно RAII)
- препроцессор (практически никогда не нужен. Вместо этого предпочитаю шаблоны)
Конечно, есть исключения для каждого из этих пунктов, но, как правило, код C ++, в отличие от кода C, в значительной степени исключает любое их использование.
И больше, чем в C #, классы - действительно рабочие лошадки, выполняющие большую работу. В C # класс - это не более чем скаффолдинг, контейнер для размещения всех ваших методов. Конечно, у него есть конструктор, и он может реализовать Dispose (); но C ++ делает это намного дальше, и у вас есть:
- Конструктор (как в C #, который инициализирует класс с нуля)
- Конструктор копирования (инициализирует класс как копию другого объекта)
- Оператор присваивания (поскольку классы - это то, что в C # рассматривает типы-значения. И поэтому присваивание - это не просто изменение ссылки, а копирование всего содержимого объекта, определяемое пользователем)
- Деструктор
Деструктор, вероятно, самая важная концепция в C ++. Это жизненно важно для RAII, то есть для управления памятью или другими ресурсами, потому что он автоматически вызывается, когда объект выходит из области видимости. Это позволяет вашим классам давать множество гарантий, которых невозможно достичь в C или C #.
Например, boost :: thread предоставляет блокированные области действия, которые гарантированно освобождаются, когда выходят из области видимости, возвращается ли функция нормально, генерируется ли исключение или что-то еще. Поэтому при использовании этой библиотеки пользователю не нужно беспокоиться об освобождении блокировок или других ресурсов. Это происходит автоматически, как только вы закончите с ними.
В некотором смысле это дает вам гораздо больше возможностей для настройки поведения вашего класса. В отличие от C #, вы точно контролируете, что происходит при выполнении простого присваивания. Вы управляете тем, что происходит, когда класс выходит из области видимости, когда он инициализируется с нуля или является копией другого объекта. Это позволяет практически невозможно использовать неправильно написанный класс. (Почти)
Помимо этого, шаблоны и метапрограммирование шаблонов - это концепции, с которыми вы, вероятно, столкнетесь. Это чрезвычайно мощные инструменты, поэтому убедитесь, что вы дружите с ними. :)