Wie unterschiedlich ist Objective-C von C ++? [geschlossen]

171

Was sind die Hauptunterschiede zwischen Objective-C und C ++ in Bezug auf Syntax, Funktionen, Paradigmen, Frameworks und Bibliotheken?

* Wichtig: Mein Ziel ist es nicht, einen Leistungskrieg zwischen den beiden Sprachen zu beginnen. Ich möchte nur wirklich harte Fakten. Tatsächlich bezieht sich meine Frage nicht auf die Leistung! Bitte geben Sie Quellen für alles an, was subjektiv erscheint.

Wachsamkeit
quelle
2
Diese Anleitung bietet den besten Vergleich, den ich gesehen habe.
LiraNuna
@Oskar Kjellin: Die Antworten von Mac und LiraNuna sind beide ausgezeichnete Antworten. Ich kann nicht objektiv entscheiden, welches das beste ist, da beide die Antwort des anderen ergänzen.
Alarm
@Alerty gut ich weiß (stolpere ziemlich oft selbst darüber). Vielleicht markieren Sie einfach die oberste als beantwortet, was ich tue, wenn ich mich nicht entscheiden kann. Ich mag es nicht, wenn es Fragen gibt, die nicht als beantwortet markiert sind, wenn sie sind :(
Oskar Kjellin
1
Setzen Sie einen Link zur zweiten Antwort in die erste und umgekehrt
Lee Taylor

Antworten:

185

Kurze Liste einiger der wichtigsten Unterschiede:

  • C ++ erlaubt Mehrfachvererbung, Objective-C nicht.
  • Im Gegensatz zu C ++ ermöglicht Objective-C die Benennung von Methodenparametern, und die Methodensignatur enthält nur die Namen und Typen der Parameter und den Rückgabetyp (siehe Kommentare von bbum und Chuck unten). Im Vergleich dazu enthält eine C ++ - Mitgliedsfunktionssignatur den Funktionsnamen sowie nur die Typen der Parameter / Rückgabe (ohne deren Namen).
  • C ++ verwendet bool, trueund false, Objective-C Anwendungen BOOL, YESund NO.
  • C ++ verwendet void*und nullptr, Objective-C bevorzugt idund nil.
  • Objective-C verwendet "Selektoren" (die einen Typ haben SEL) als ungefähres Äquivalent zu Funktionszeigern.
  • Objective-C verwendet ein Messaging-Paradigma (a la Smalltalk), mit dem Sie über Methoden / Selektoren "Nachrichten" an Objekte senden können.
  • Mit Objective-C können Sie gerne eine Nachricht an senden nil, im Gegensatz zu C ++, das abstürzt, wenn Sie versuchen, eine Mitgliedsfunktion von aufzurufennullptr
  • Objective-C ermöglicht einen dynamischen Versand, sodass die Klasse, die auf eine Nachricht reagiert, zur Laufzeit bestimmt werden kann, im Gegensatz zu C ++, bei dem das Objekt, auf das eine Methode aufgerufen wird, zur Kompilierungszeit bekannt sein muss (siehe Kommentar von wilhelmtell unten). Dies hängt mit dem vorherigen Punkt zusammen.
  • Objective-C ermöglicht die automatische Generierung von Accessoren für Mitgliedsvariablen mithilfe von "Eigenschaften".
  • Mit Objective-C können selfKlasseninitialisierer (ähnlich wie Konstruktoren) eine völlig andere Klasse zurückgeben, falls dies gewünscht wird. Im Gegensatz zu C ++ wird beim Erstellen einer neuen Instanz einer Klasse (entweder implizit auf dem Stapel oder explizit über new) garantiert, dass sie vom ursprünglich angegebenen Typ ist.
  • In ähnlicher Weise können in Objective-C auch andere Klassen eine Zielklasse zur Laufzeit dynamisch ändern, um Methodenaufrufe abzufangen.
  • In Objective-C fehlt die Namespace-Funktion von C ++.
  • In Objective-C fehlt ein Äquivalent zu C ++ - Referenzen.
  • In Objective-C fehlen Vorlagen, die (zum Beispiel) lieber eine schwache Eingabe in Containern zulassen.
  • Objective-C erlaubt keine implizite Methodenüberladung, C ++ jedoch. Das heißt, in C ++ int foo (void)und int foo (int)definieren Sie eine implizite Überladung der Methode foo, aber um dies in Objective-C zu erreichen, sind die expliziten Überladungen - (int) foound erforderlich - (int) foo:(int) intParam. Dies liegt daran, dass die benannten Parameter von Objective-C funktional der Namensverfälschung von C ++ entsprechen.
  • Objective-C ermöglicht es einer Methode und einer Variablen, denselben Namen zu verwenden, im Gegensatz zu C ++, das normalerweise Anpassungen aufweist. Ich stelle mir vor, dass dies etwas mit Objective-C zu tun hat, bei dem Selektoren anstelle von Funktionszeigern verwendet werden und daher Methodennamen keinen "Wert" haben.
  • In Objective-C können keine Objekte auf dem Stapel erstellt werden. Alle Objekte müssen vom Heap zugewiesen werden (entweder explizit mit einer allocNachricht oder implizit in einer geeigneten Factory-Methode).
  • Wie C ++ hat Objective-C sowohl Strukturen als auch Klassen. Wenn sie in C ++ jedoch fast genau gleich behandelt werden, werden sie in Objective-C sehr unterschiedlich behandelt - Sie können beispielsweise Strukturen auf dem Stapel erstellen.

Meiner Meinung nach ist der wahrscheinlich größte Unterschied die Syntax. Sie können in beiden Sprachen im Wesentlichen das Gleiche erreichen, aber meiner Meinung nach ist die C ++ - Syntax einfacher, während einige der Funktionen von Objective-C bestimmte Aufgaben (z. B. das GUI-Design) dank des dynamischen Versands erleichtern.

Wahrscheinlich auch viele andere Dinge, die ich verpasst habe. Ich werde sie mit allen anderen Dingen aktualisieren, an die ich denke. Abgesehen davon kann ich den Führer, auf den LiraNuna Sie hingewiesen hat, nur empfehlen. Ein anderer interessanter Ort könnte dies übrigens sein .

Ich sollte auch darauf hinweisen, dass ich gerade erst anfange, Objective-C selbst zu lernen, und daher sind viele der oben genannten Punkte möglicherweise nicht ganz richtig oder vollständig - ich entschuldige mich, wenn dies der Fall ist, und begrüße Verbesserungsvorschläge.

BEARBEITEN: aktualisiert, um die in den folgenden Kommentaren angesprochenen Punkte zu berücksichtigen, und der Liste einige weitere Elemente hinzugefügt.

Mac
quelle
8
Anständige Liste; eine Korrektur. Sie sind keine "benannten Parameter", sondern "verschachtelte Parameter". Benannte und "Schlüsselwortargumente" führen zu der Verwirrung, dass eine Teilmenge des Methodennamens weggelassen werden könnte. Es kann nicht.
bbum
7
Sie haben vergessen, den wichtigsten Unterschied anzugeben: Object-C verwendet den dynamischen Versand, während C ++ den statischen Versand verwendet. Mit anderen Worten, Code, der von einem Objective-C-Compiler kompiliert wurde, hat die Klasse, die für die Beantwortung einer zur Laufzeit bestimmten Nachricht verantwortlich ist. Bei Code, der von einem C ++ - Compiler kompiliert wurde, werden diese Informationen zur Kompilierungszeit berechnet und kompiliert.
Wilhelmtell
9
@wilhelmtell: Der C ++ - Compiler kennt zur Kompilierungszeit nur die Oberklasse. Zur Laufzeit kann die eigentliche Klasse ein beliebiger Nachkomme sein. Dies ist auch eine Form des dynamischen Versands, jedoch nicht die gleiche Form wie in Ziel C. Seien Sie nur vorsichtig mit diesen technischen Begriffen!
Norman Ramsey
5
+1 Gute Liste. Objective-C verwendet jedoch auch void*und NULLnur nicht für Objekte. Sie können in Obj-C einen beliebigen Zeiger im C-Stil verwenden, und viele API-Aufrufe übergeben oder geben Werte tatsächlich als Referenz zurück. In diesem Fall NULLwird sie häufig verwendet.
Quinn Taylor
3
@wilhelmtell - Ich weiß nichts über Objective-C, aber in C ++ KANN eine andere Klasse dynamisch auf einen Funktionsaufruf reagieren, aber Sie müssten so etwas wie ein Array von Zeigern auf eine Basisklasse und dann die ACTUAL-Klassen haben das "hängen" davon ab. Während alle Klassen Unterklassen enthalten müssen, ruft ein Methodenaufruf zur Laufzeit je nach Klasse unterschiedliche Methoden auf.
Kevin Anderson
33

Während beide in C verwurzelt sind, sind sie zwei völlig verschiedene Sprachen.

Ein wesentlicher Unterschied besteht darin, dass sich Objective-C auf Laufzeitentscheidungen für den Versand konzentriert und stark von seiner Laufzeitbibliothek abhängt, um Vererbung und Polymorphismus zu handhaben, während in C ++ der Fokus normalerweise auf statischen Entscheidungen zur Kompilierungszeit liegt.

In Bezug auf Bibliotheken können Sie einfache C-Bibliotheken in beiden Sprachen verwenden - ihre nativen Bibliotheken sind jedoch völlig unterschiedlich.

Interessant ist jedoch, dass Sie beide Sprachen mischen können (mit einigen Einschränkungen). Das Ergebnis heißt Objective-C ++ .

Georg Fritzsche
quelle
aktualisierter Link: Objective-C ++
IcyIcicle
6

Sie sind völlig anders. Ziel C hat mehr mit Smalltalk gemeinsam als mit C ++ (naja, bis auf die Syntax wirklich).

Dean Harding
quelle
6

Aus dem Kopf:

  1. Stile - Obj-C ist dynamisch, C ++ ist normalerweise statisch
  2. Obwohl beide OOP sind, bin ich sicher, dass die Lösungen unterschiedlich wären.
  3. Anderes Objektmodell (C ++ ist durch sein System vom Typ der Kompilierungszeit eingeschränkt).

Der größte Unterschied ist für mich das Modellsystem. Mit Obj-C können Sie Messaging und Introspektion durchführen, aber C ++ verfügt über die leistungsstarken Vorlagen.

Jeder hat seine Stärken.

Rev316
quelle
5

Wie andere gesagt haben, ist Objective-C viel dynamischer in Bezug auf die Denkweise von Objekten im Vergleich zu C ++ 's ziemlich statischem Bereich.

Objective-C gehört zur Smalltalk-Linie objektorientierter Sprachen und hat ein Konzept von Objekten, das dem von Java, Python und anderen objektorientierten Nicht-C ++ - Standardsprachen sehr ähnlich ist. Viel dynamischer Versand, keine Überlastung des Bedieners, Nachrichten senden.

C ++ ist ein seltsames Tier. Der Smalltalk-Teil des Stammbaums wurde größtenteils übersprungen. In gewisser Weise verfügt es über ein gutes Modulsystem mit Unterstützung für die Vererbung, das zufällig für die objektorientierte Programmierung verwendet werden kann. Die Dinge sind viel statischer (überschreibbare Methoden sind zum Beispiel nicht die Standardeinstellung).

Michael Ekstrand
quelle
4

Objective-C ist eine perfektere Obermenge von C. In C und Objective-C ist implizites Casting von void*zu einem Strukturzeiger zulässig.

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

C ++ wird nur kompiliert, wenn der voidZeiger explizit umgewandelt wird:

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

Die Relevanz für die tägliche Programmierung ist Null, nur eine lustige Trivia-Tatsache.

Igor Zevaka
quelle
Das zweite Beispiel ist kein C ++ - Code. Es ist C-Code, der Ihnen einen Fehler gab, als Sie versuchten, ihn mit dem C ++ - Compiler zu kompilieren. Wenn Sie möchten, dass altes C ++ dem Original so nahe kommt, würden Sie schreiben und Foo* bar = reinterpret_cast< Foo* >(malloc(sizeof(Foo));dann vielleicht den Inplace-Konstruktor verwenden. Aber ab heute ist das moderne C ++ eher so auto bar = new Foo(constructorArg);, als ob Sie kein Malloc benötigen, und Sie können entweder Callic verwenden std::vector::reserve, undstd::vector::emplace_mack
xakepp35
3

Obj-C verfügt über viel dynamischere Funktionen in der Sprache selbst, während sich C ++ mehr auf Funktionen zur Kompilierungszeit mit einigen dynamischen Funktionen konzentriert.

In wird der parametrische C ++ - Polymorphismus zur Kompilierungszeit überprüft, während in Obj-C der parametrische Polymorphismus durch dynamischen Versand erreicht wird und zur Kompilierungszeit nicht überprüft wird.

Obj-C ist von Natur aus sehr dynamisch. Sie können einer Klasse zur Laufzeit Methoden hinzufügen. Außerdem wird zur Laufzeit eine Selbstbeobachtung durchgeführt, um Klassen zu betrachten. In C ++ kann sich die Definition der Klasse nicht ändern, und die gesamte Selbstbeobachtung muss zur Kompilierungszeit erfolgen. Obwohl die Dynamik von Obj-C in C ++ mithilfe einer Funktionskarte (oder ähnlichem) erreicht werden könnte, ist sie immer noch ausführlicher als in Obj-C.

In C ++ gibt es viel mehr Überprüfungen, die zur Kompilierungszeit durchgeführt werden können. Beispielsweise kann der Compiler mithilfe eines Variantentyps (wie einer Union) erzwingen, dass alle Fälle geschrieben oder behandelt werden. Sie vergessen also nicht, die Randfälle eines Problems zu behandeln. Alle diese Prüfungen haben jedoch beim Kompilieren einen Preis. Obj-C kompiliert viel schneller als C ++.

Paul Fultz II
quelle
3
Wenn Sie über Preise sprechen, seien Sie fair! Umgekehrt löst Obj-C dynamische Methodenaufrufe zur Laufzeit viel langsamer auf als C ++. Und ich würde argumentieren, dass die Kompilierungsgeschwindigkeit im Vergleich zur Laufzeitgeschwindigkeit eine relative Trivialität ist. Ich bin sicher, dass Obj-C aufgrund seines dynamischeren Versands viele Vorteile bietet, aber es gibt dort einen Kompromiss.
underscore_d
1
Es stimmt, es gibt einen Kompromiss zwischen Laufzeit- und Kompilierungszeitkosten. Die Kompilierungszeit ist jedoch nicht immer trivial. Die Verwendung umfangreicher Metaprogrammier- und EDSL-Bibliotheken in C ++ (wie Boost.Spirit) kann sich drastisch auf die Kompilierungszeit auswirken und gleichzeitig zur Laufzeit sehr schnellen Code erzeugen.
Paul Fultz II
1
Sicher, ich habe mich im Vergleich zum POV einfacher Codebasen zu stark vereinfacht ... Bei sehr komplexen Codebasen kann das Neukompilieren zum Testen kleiner Änderungen die Entwicklung sehr mühsam machen, was keine Trivialität ist. Aber können wir das wirklich miteinander vergleichen? Können solche Bibliotheken, die so abhängig von C ++ - Funktionen zur Kompilierungszeit sind, in Objective-C irgendwie neu interpretiert und schneller kompiliert werden? dh Bezieht sich die Aussage "Obj-C kompiliert viel schneller als C ++" auf äquivalente Codebasen, für die eine replizierbare Beschleunigung gemessen werden kann? Ansonsten vergleichen wir die Zeit, die für den Anbau von Äpfeln benötigt wird, mit Orangen.
underscore_d