Каковы принципиальные различия между C и C ++? [закрыто]

41

Многие склонны писать «C / C ++», как если бы они были одним и тем же. Хотя они имеют много общего, они явно не совпадают.

Но каковы действительно фундаментальные различия между C и C ++? Является ли C ++ улучшенной версией C или в C ++ есть функции, которых нет в C ++?

gablin
источник
2
Я думал, что C ++ - супер набор C
пользователь
1
C ++ не улучшен ... это расширенный набор C ..
Джо Д. Ф.
2
@JoeDF Это было в самом начале, но сейчас оно «совместимо с C», что вовсе не означает одно и то же. Вы не пишете код на C в C ++, и не все стандартные C совместимы со стандартом C ++.
Klaim
+1 Вы правы, теперь есть как братья или двоюродные братья. Если вы понимаете, о чем я.
Джо Д.Ф.

Ответы:

43

Следующие пункты относятся к C ++:

  1. (определяемая пользователем) система статических типов: позволяет проводить статические проверки ваших данных и их использование - указывает на множество легко совершаемых ошибок в C.
  2. мульти-«парадигма»: позволяет работать как в C, с объектно-ориентированными парадигмами, с общими парадигмами и т. д.
  3. Конструктор / Деструктор: единственный способ один раз сказать, что делать при создании или уничтожении чего-либо, и быть уверенным, что пользователю не придется находить нужную функцию и использовать ее, как в C.
  4. RAII (плохо назван): вам не всегда нужно управлять памятью. Просто держите вещи в поле зрения и используйте умные указатели, описывающие время жизни ваших объектов. Все еще можете использовать сырые указатели.
  5. Шаблоны: лучше, чем макрос, настоящий язык для манипулирования и генерации типов перед окончательной компиляцией. Отсутствует только система типов (см. Концепции в будущих стандартах C ++).
  6. Операторские перегрузки: позволяет описывать операции простым синтаксическим способом и даже определять встроенные предметно-ориентированные языки внутри вашего кода C ++.
  7. Имена областей: пространства имен, классы / структура, функции и т. Д. Имеют простые правила, чтобы убедиться, что имена не конфликтуют.
  8. Система исключений: способ распространения ошибок, который часто лучше, чем код возврата. Фактически, код возврата подходит для логических ошибок, связанных с доменом, потому что приложение должно управлять им. Исключения используются для «серьезных» ошибок, которые делают следующий код просто некорректным. Он позволяет перехватывать ошибки выше в стеке вызовов, если это возможно, реагировать на такое исключение (путем регистрации или исправления состояния) и с помощью RAII, если он хорошо используется, не делает всю программу неправильной - если все сделано хорошо, снова.
  9. Стандартная библиотека: C имеет свою собственную, но все это «динамично». Стандартная библиотека C ++ почти (не потоки ввода-вывода) состоит из шаблонов (контейнеров и алгоритмов), которые позволяют генерировать код только для того, что вы используете. Лучше: так как компилятор должен генерировать код, он будет много знать о контексте и с радостью применяет много оптимизаций, не требуя, чтобы кодер запутывал свой код - благодаря шаблонам и другим вещам.
  10. const-правильность: лучший способ убедиться, что вы не меняете переменные, которые вы не должны. Позволяет указать доступ только для чтения к переменным. И это проверяется только во время компиляции, поэтому нет затрат времени выполнения.
Klaim
источник
31

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

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

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

Наконец, ООП предлагает множество других преимуществ, таких как повторное использование объектов, а также общие концепции, основанные на программировании, такие как шаблоны и шаблоны, которые позволяют повторно использовать исходный код и т. Д.

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

Jas
источник
Мне нравится, что вы пишете о конструкторе C ++ против структур C, и что он подвержен ошибкам. Я согласен с этим. Но мне не нравится способ использования Java в JavaBeans, который всегда использует пустой конструктор, а затем устанавливает поля-члены с помощью установщиков. На мой взгляд, это так же подвержено ошибкам, как и C. Я бы предпочел устанавливать мои объекты Java только с помощью конструктора. Смотрите мой вопрос на StackOverflow об этом.
Джонас
У вас есть точка зрения, но в центре моего ответа здесь был C против C ++.
Jas
1
Да ладно, кто мешает вам использовать ООП с C? Вы можете повторно использовать объекты и делать что угодно, даже исключения. Есть даже книга об этом, называемая ООП программирование на C.
2
@ Влад, ничего из того, о чем ты говоришь, не было выбора 25 лет назад.
Jas
4
Вы МОЖЕТЕ делать ООП практически на каждом языке программирования, который все еще используется, но это не значит, что язык был разработан для него. Взять, к примеру, Луа. Хотя технически это позволяет ООП, кажется, существует около пятидесяти различных способов сделать это, что вызывает сильную головную боль.
Tyjkenn
15

В общем, все, что существует в C, поддерживается в C ++. Очевидно, что обратное абсолютно неверно.

Проще говоря, C ++ является объектно-ориентированным (например, у вас есть классы), а C - нет.

C ++ имеет логический тип, а C89 - нет.

Это разные языки. Они просто разделяют большую часть синтаксиса.

Федерико Клез Каллока
источник
4
C99 имеет логический тип (по имени _Bool, с boolпсевдонимом).
Джерри Гроб
1
Это не совсем верно. Например, C99 имеет long longтип данных, который (пока) не является частью ISO C ++.
Чинмай Канчи
11
Err ... C ++ не только объектно-ориентированный: вы можете использовать объектно-ориентированные парадигмы с C ++, потому что язык предоставляет возможности для этого, но он также предоставляет возможности и для других парадигм. Вы должны упомянуть, что это действительно важно, это все меняет. Если бы этого не произошло, мы бы все переключились на Java ...
Klaim
4
Есть много конструкций в C, которые не работают в C ++.
1
@klez: да - но все равно это не так. В то время как ANSI изначально разрабатывал C89 (который не имел булева типа), новая разработка теперь выполняется ISO, и ANSI принимает стандарт ISO, поэтому текущий стандарт ANSI C идентичен текущему стандарту ISO C (который имеет логический тип).
Джерри Гроб
8

C99 имеет несколько функций, которые не существуют (по крайней мере, в той же форме) в C ++ (например, гибкие элементы массива, массивы переменной длины и т. Д.)

C99 также много добавил в библиотеку, которой нет в стандарте C ++ 98/03; большая часть этого была добавлена ​​в C ++ 11.

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

Джерри Гроб
источник
1

Лично я считаю, что шаблоны - это самая важная особенность, которую C ++ добавляет в C.

zvrba
источник
1
А как насчет классов с наследованием? Это действительно тяжелая работа в C, в то время как многие шаблоны могут быть выполнены с помощью макроса препроцессора.
JBRWilkinson
4
Макросы препроцессора небезопасны; это просто текстовая замена, что также затрудняет отладку. Получить базовые классы и наследование для работы не так уж много в C. + вы можете создать свою собственную модель метаобъекта вместо того, чтобы зацикливаться на том, что разработчик языка выбрал для вас. См., Например, этот документ: arxiv.org/abs/1003.2547
zvrba
2
Я проголосовал бы за деструкторы за самую значимую особенность, которая есть у C ++ над C (даже за конструкторы из-за их потрясающих возможностей очистки).
Томас Эдинг
@zvrba #define GENERATE_INTERFACE(T) T T##_func(T x);; (тип) безопасная перегрузка / шаблоны в C. Я согласен с Томасом в том, что деструкторы - гораздо более важная функция, в которой отсутствует C. Но деструкторы часто скрывают важный код. Пространства имен (область), на мой взгляд, являются наиболее важными.
YoYoYonnY