Насколько Objective-C отличается от C ++? [закрыто]

171

Каковы основные различия между Objective-C и C ++ с точки зрения синтаксиса, функций, парадигм, каркасов и библиотек?

* Важно: моя цель не состоит в том, чтобы начать войну между двумя языками. Я хочу только очень веских фактов. На самом деле мой вопрос не связан с производительностью! Пожалуйста, дайте источники для всего, что может показаться субъективным.

Alerty
источник
2
Это руководство дает лучшее сравнение, которое я видел.
LiraNuna
@ Оскар Кьеллин: Ответы Mac и LiraNuna - оба отличные ответы. Я не могу объективно решить, какой из них лучший, потому что оба они дополняют ответ друг друга.
Предупреждение
@ Хорошо знаю, хорошо знаю (сам сталкиваюсь с этим). Возможно, просто пометьте верхний ответ как ответ, который я делаю, когда не могу решить. Мне не нравится, когда есть вопросы, не помеченные как отвеченные, когда они есть :(
Оскар Кьеллин
1
Поместите ссылку на второй ответ в первом и наоборот
Ли Тейлор

Ответы:

185

Краткий список некоторых основных отличий:

  • C ++ допускает множественное наследование, Objective-C - нет.
  • В отличие от C ++, Objective-C позволяет именовать параметры метода, а сигнатура метода включает в себя только имена и типы параметров и тип возвращаемого значения (см. Комментарии bbum и Чака ниже). Для сравнения, сигнатура функции-члена C ++ содержит имя функции, а также только типы параметров / возврата (без их имен).
  • C ++ использует bool, trueи false, Objective-C использует BOOL, YESи NO.
  • C ++ использует void*и nullptr, Objective-C предпочитает idи nil.
  • Objective-C использует «селекторы» (которые имеют тип SEL) в качестве приблизительного эквивалента указателям на функции.
  • Objective-C использует парадигму обмена сообщениями (а-ля Smalltalk), где вы можете отправлять «сообщения» объектам с помощью методов / селекторов.
  • Objective-C с радостью позволит вам отправить сообщение nil, в отличие от C ++, который вылетит, если вы попытаетесь вызвать функцию-членnullptr
  • Objective-C допускает динамическую диспетчеризацию, позволяя классу, отвечающему на сообщение, быть определенным во время выполнения, в отличие от C ++, где объект, к которому вызывается метод, должен быть известен во время компиляции (см. Комментарий wilhelmtell ниже). Это связано с предыдущим пунктом.
  • Objective-C позволяет автоматически генерировать методы доступа для переменных-членов, используя «свойства».
  • Objective-C позволяет присваивать selfи инициализаторам класса (подобно конструкторам) возвращать совершенно другой класс, если это необходимо. В отличие от C ++, где, если вы создаете новый экземпляр класса (либо неявно в стеке, либо явно через new), он гарантированно будет того типа, который вы указали изначально.
  • Аналогично, в Objective-C другие классы также могут динамически изменять целевой класс во время выполнения, чтобы перехватывать вызовы методов.
  • В Objective-C отсутствует функция пространства имен C ++.
  • В Objective-C отсутствует эквивалент ссылок на C ++.
  • В Objective-C отсутствуют шаблоны, предпочитающие (например) вместо этого разрешать слабую типизацию в контейнерах.
  • Objective-C не допускает неявную перегрузку методов, но C ++ делает. То есть в C ++ int foo (void)и int foo (int)определяют неявную перегрузку метода foo, но для достижения того же в Objective-C требуются явные перегрузки - (int) fooи - (int) foo:(int) intParam. Это связано с тем, что именованные параметры Objective-C функционально эквивалентны искажению имен в C ++.
  • Objective-C, к счастью, позволит методу и переменной иметь одно и то же имя, в отличие от C ++, который обычно подходит. Я предполагаю, что это как-то связано с Objective-C, использующим селекторы вместо указателей на функции, и, следовательно, имена методов, фактически не имеющие «значения».
  • Objective-C не позволяет создавать объекты в стеке - все объекты должны быть выделены из кучи (либо явно с allocсообщением, либо неявно в соответствующем методе фабрики).
  • Как и C ++, Objective-C имеет как структуры, так и классы. Однако в тех случаях, когда в C ++ они обрабатываются практически одинаково, в Objective-C они обрабатываются совершенно по-разному - например, вы можете создавать структуры в стеке.

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

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

Я также должен отметить, что я только начинаю изучать Objective-C сам, и поэтому многое из вышеперечисленного может быть не совсем правильным или полным - я прошу прощения, если это так, и приветствую предложения по улучшению.

РЕДАКТИРОВАТЬ: обновлено с учетом вопросов, поднятых в следующих комментариях, добавлено еще несколько пунктов в список.

макинтош
источник
8
Достойный список; одна поправка. Это не «именованные параметры», а «чередующиеся параметры». Именованные и «ключевые аргументы» приводят к путанице, когда некоторые подмножества имени метода могут быть опущены. Оно не может.
bbum
7
Вы забыли включить самое важное отличие: Object-C использует динамическую диспетчеризацию, тогда как C ++ использует статическую диспетчеризацию. Другими словами, код, скомпилированный компилятором Objective C, будет иметь класс, отвечающий за ответ на сообщение, определенное во время выполнения; код, скомпилированный компилятором C ++, рассчитывает и компилирует эту информацию во время компиляции.
wilhelmtell
9
@wilhelmtell: компилятор C ++ знает только суперкласс во время компиляции. Во время выполнения класс может быть любым потомком. Это также форма динамической отправки, но не та, которая используется в Objective C. Просто будьте осторожны с этими техническими терминами!
Норман Рэмси
5
+1 Хороший список. Однако Objective-C также использует void*и NULL, но не для объектов. Вы можете использовать любой указатель в стиле C в Obj-C, и многие вызовы API фактически передают или возвращают значения по ссылке, и в этом случае NULLчасто используется.
Куинн Тейлор
3
@wilhelmtell - я ничего не знаю о target-C, но в C ++ вы МОЖЕТЕ динамически заставить другой класс реагировать на вызов функции, но вам нужно иметь что-то вроде массива указателей на базовый класс, а затем классы ACTUAL которые "висят" от него. Хотя все классы должны быть подклассами, вызов метода будет вызывать разные методы в зависимости от класса во время выполнения.
Кевин Андерсон
33

Хотя они оба основаны на C, это два совершенно разных языка.

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

Что касается библиотек, вы можете использовать простые библиотеки C на обоих языках, но их нативные библиотеки совершенно разные.

Интересно, однако, что вы можете смешивать оба языка (с некоторыми ограничениями). Результат называется Objective-C ++ .

Георг Фрицше
источник
обновленная ссылка: Objective-C ++
IcyIcicle
6

Они совершенно разные. Objective C имеет больше общего с Smalltalk, чем с C ++ (ну, за исключением синтаксиса, на самом деле).

Дин Хардинг
источник
6

С верхней части моей головы:

  1. Стили - Obj-C динамический, C ++ обычно статический
  2. Хотя они оба ООП, я уверен, что решения будут разными.
  3. Другая объектная модель (C ++ ограничен системой типов во время компиляции).

Для меня самая большая разница в модели системы. Obj-C позволяет вам осуществлять обмен сообщениями и самоанализ, но C ++ имеет очень мощные шаблоны.

У каждого есть свои сильные стороны.

Rev316
источник
5

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

Objective-C, находящийся в линии Smalltalk объектно-ориентированных языков, имеет концепцию объектов, которая очень похожа на концепцию Java, Python и других "стандартных" неоригинальных объектно-ориентированных языков. Много динамической отправки, без перегрузки операторов, отправка сообщений.

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

Майкл Экстранд
источник
4

Objective-C является более совершенным надмножеством C. В C и Objective-C void*допускается неявное приведение к указателю структуры.

Foo* bar = malloc(sizeof(Foo));

C ++ не будет компилироваться, если voidуказатель явно не приведен:

Foo* bar = (Foo*)malloc(sizeof(Foo));

Актуальность этого для повседневного программирования равна нулю, просто забавный факт.

Игорь Зевака
источник
Второй пример - это не код C ++. Это код C, который выдает ошибку, когда вы пытаетесь скомпилировать его с помощью компилятора C ++. Если вы хотите, чтобы старый C ++ был максимально приближен к оригинальному, вы могли бы написать, а Foo* bar = reinterpret_cast< Foo* >(malloc(sizeof(Foo));затем использовать встроенный конструктор. Но на сегодняшний день его Modern C ++ больше похож auto bar = new Foo(constructorArg);на то, что вам фактически не нужен malloc, и вы можете использовать либо callic std::vector::reserve, иstd::vector::emplace_mack
xakepp35
3

Obj-C имеет гораздо больше динамических возможностей в самом языке, тогда как C ++ больше ориентирован на возможности времени компиляции с некоторыми динамическими возможностями.

В C ++ параметрический полиморфизм проверяется во время компиляции, тогда как в Obj-C параметрический полиморфизм достигается посредством динамической диспетчеризации и не проверяется во время компиляции.

Obj-C очень динамичен по своей природе. Вы можете добавлять методы в класс во время выполнения. Кроме того, он имеет самоанализ во время выполнения, чтобы посмотреть на классы. В C ++ определение класса не может измениться, и весь самоанализ должен быть выполнен во время компиляции. Хотя динамическая природа Obj-C может быть достигнута в C ++ с использованием карты функций (или чего-то подобного), она все еще более многословна, чем в Obj-C.

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

Пол Фульц II
источник
3
Если вы собираетесь говорить о ценах, будьте справедливы! И наоборот, Obj-C намного медленнее обрабатывает вызовы динамических методов во время выполнения, чем C ++. И я бы сказал, что скорость компиляции является относительной тривиальностью по сравнению со скоростью выполнения. Я уверен, что Obj-C предлагает много преимуществ из-за его более динамичной отправки, но здесь есть компромисс.
underscore_d
1
Правда, существует компромисс между временем выполнения и стоимостью времени компиляции. Однако время компиляции не всегда тривиально. Использование тяжелого метапрограммирования и библиотек EDSL в C ++ (таких как Boost.Spirit) может оказать существенное влияние на время компиляции, в то же время создавая очень быстрый код во время выполнения.
Пол Фульц II
1
Конечно, я слишком упрощенно относился к POV более простых кодовых баз ... С очень сложными кодовыми базами перекомпиляция для тестирования небольших изменений может сделать разработку очень утомительной, что не является тривиальностью. Но это то, что мы действительно можем сравнить между двумя? Можно ли каким-то образом переосмыслить такие библиотеки, так зависящие от функций времени компиляции C ++, в Objective-C и показать, что они компилируются быстрее? т. е. относится ли утверждение «Obj-C к компиляции намного быстрее, чем C ++» к эквивалентным кодовым базам, для которых можно измерить воспроизводимое ускорение? В противном случае мы сравниваем время выращивания яблок с апельсинами.
underscore_d