Наскільки відрізняється Objective-C від C ++? [зачинено]


171

Які основні відмінності між Objective-C та C ++ з точки зору синтаксису, особливостей, парадигм, рамок та бібліотек?

* Важливо: Моя мета - не розпочати війну між двома мовами. Я хочу лише справжніх важких фактів. Насправді моє запитання не пов’язане з виконанням! Будь ласка, дайте джерела для всього, що може здатися суб’єктивним.


2
Цей посібник дає найкраще порівняння, що я бачив.
LiraNuna

@Oskar Kjellin: Відповіді Mac та LiraNuna - це чудові відповіді. Я не можу об'єктивно вирішити, який із них найкращий, тому що обидва доповнюють відповіді один одного.
Алерті

@Alerty добре я знаю (натрапляю на це досить часто сам). Можливо, просто позначте верхню як відповідь, що я роблю, коли не можу визначитися. Мені не подобається, коли є запитання, не позначені як відповіді, коли вони є :(
Оскар Келлін

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 використовує парадигму обміну повідомленнями (a la 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 сам, і як таке багато вищезазначеного може бути не зовсім коректним або повним - прошу вибачення, якщо це так, і вітаю пропозиції щодо вдосконалення.

EDIT: оновлено для вирішення питань, викладених у наступних коментарях, додав до списку ще кілька пунктів.


8
Достойний список; одна корекція. Вони не "названі параметри", а "перемежовані параметри". Названі та "аргументи ключових слів" призводять до плутанини думки про те, що деякий підмножина назви методу може бути пропущено. Це не може.
bbum

7
Ви забули зарахувати найважливішу різницю: Object-C використовує динамічну доставку, тоді як C ++ використовує статичну. Іншими словами, код, складений компілятором Objective-C, матиме клас, відповідальний за відповідь на повідомлення, визначене під час виконання; Код, зібраний компілятором C ++, цю інформацію розраховує та збирає під час компіляції.
wilhelmtell

9
@wilhelmtell: Компілятор C ++ знає лише суперклас під час компіляції. Під час виконання фактичним класом може бути будь-який нащадок. Це також форма динамічної відправки, але не та сама форма, яка використовується в Цілі C. Просто будьте уважні до цих технічних термінів!
Норман Рамзі

5
+1 Хороший список. Однак Objective-C також використовує void*і NULL, не тільки для об'єктів. Ви можете використовувати будь-який вказівник у стилі С у Obj-C, і багато дзвінків API фактично передають або повертають значення за посиланням, у цьому випадку NULLчасто використовується.
Квінн Тейлор

3
@wilhelmtell - я нічого не маю на увазі в об'єкті-C, але в C ++ ви МОЖЕТЕ динамічно мати інший клас, який відповідає на виклик функції, але вам потрібно мати щось на зразок масиву покажчиків до базового класу, а потім класів ACTUAL які "звисають" від цього. Хоча всі класи там повинні бути підкласами, виклик методу БУДЕ викликати різні методи залежно від класу під час виконання.
Кевін Андерсон

33

Поки вони обидва вкорінені в C, вони є двома абсолютно різними мовами.

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

Щодо бібліотек, ви можете використовувати звичайні бібліотеки С обома мовами - але їхні рідні бібліотеки абсолютно різні.

Однак цікаво те, що ви можете змішувати обидві мови (з деякими обмеженнями). Результат називається Objective-C ++ .


оновлене посилання: Objective-C ++
IcyIcicle

6

Вони зовсім інші. Мета C має більше спільного з Smalltalk, ніж із C ++ (ну, крім синтаксису, насправді).


6

Вгорі голови:

  1. Стилі - Obj-C є динамічним, C ++, як правило, статичним
  2. Хоча вони обоє OOP, я впевнений, що рішення були б іншими.
  3. Інша модель об'єкта (C ++ обмежена системою типів компіляції часу).

Для мене найбільша різниця - модель моделі. Obj-C дозволяє робити обмін повідомленнями та самоаналіз, але C ++ має завжди настільки потужні шаблони.

У кожного свої сильні сторони.


5

Як говорили інші, Objective-C набагато більш динамічний з точки зору того, як він думає про об'єкти порівняно з досить статичною цариною C ++.

Objective-C, що знаходиться в лінійці Smalltalk об'єктно-орієнтованих мов, має поняття об'єктів, дуже схоже на поняття Java, Python та інших "стандартних", не-C ++ об'єктно-орієнтованих мов. Багато динамічної відправки, без перевантаження оператора, надсилання повідомлень навколо.

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));тоді використовуйте конструктор inplace. Але на сьогоднішній день його сучасний 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 ++.


3
Якщо ви збираєтесь поговорити про ціни, будьте справедливими! І навпаки, Obj-C набагато повільніше при вирішенні динамічних викликів методів під час виконання, ніж C ++. І я б заперечував, що швидкість компіляції є відносною тривіальністю порівняно зі швидкістю виконання. Я впевнений, що Obj-C пропонує багато переваг завдяки більш динамічній розсилці, але там є компроміс.
підкреслюй_d

1
Правда, існує компроміс між часом виконання та компіляцією. Однак час компіляції не завжди є тривіальним. Використання важких метапрограмувань та бібліотек EDSL в C ++ (наприклад, Boost.Spirit) може мати різкий вплив на час компіляції, створюючи при цьому дуже швидкий код під час виконання.
Пол Фульц II

1
Звичайно, я був надто спрощеним щодо POV більш простих кодових баз ... З дуже складними базами коду перекомпіляція для тестування невеликих змін може зробити розробку дуже стомлюючою, що не є дрібницею. Але чи це ми можемо насправді порівняти між собою? Чи можуть такі бібліотеки, настільки залежні від функцій часу компіляції на C ++, якось переробитись у Objective-C & показано, щоб вони швидше збиралися? тобто, чи твердження "Obj-C набагато швидше при компілюванні, ніж C ++", посилається на еквівалентні кодові бази, для яких можна виміряти прискорене прискорення? Інакше ми порівнюємо час, необхідний для вирощування яблук проти апельсинів.
підкреслюй_
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.