Quanto è diverso Objective-C da C ++? [chiuso]


171

Quali sono le principali differenze tra Objective-C e C ++ in termini di sintassi, caratteristiche, paradigmi, framework e librerie?

* Importante: il mio obiettivo non è iniziare una guerra di performance tra le due lingue. Voglio solo fatti concreti. In effetti, la mia domanda non è correlata alle prestazioni! Si prega di fornire fonti per tutto ciò che può sembrare soggettivo.


2
Questa guida offre il miglior confronto che abbia mai visto.
LiraNuna,

@Oskar Kjellin: Le risposte di Mac e LiraNuna sono entrambe risposte eccellenti. Non riesco a decidere obiettivamente quale sia il migliore perché entrambi completano la risposta dell'altro.
Alerty,

@Alerty bene lo so (inciampare in questo piuttosto spesso me stesso). Forse basta contrassegnare quello in alto come risposta, che è quello che faccio quando non riesco a decidere. Non mi piace quando ci sono domande non contrassegnate come risposte quando sono :(
Oskar Kjellin

1
Inserisci un link alla seconda risposta nel primo e viceversa
Lee Taylor,

Risposte:


185

Breve elenco di alcune delle principali differenze:

  • C ++ consente l'ereditarietà multipla, Objective-C no.
  • A differenza di C ++, Objective-C consente di nominare i parametri del metodo e la firma del metodo include solo i nomi e i tipi dei parametri e del tipo restituito (vedere i commenti di bbum e Chuck di seguito). In confronto, una firma della funzione membro C ++ contiene il nome della funzione e solo i tipi dei parametri / return (senza i loro nomi).
  • C ++ usi bool, truee false, usi Objective-C BOOL, YESe NO.
  • C ++ utilizza void*e nullptr, Objective-C preferisce ide nil.
  • Objective-C utilizza "selettori" (che hanno il tipo SEL) come equivalente approssimativo dei puntatori a funzione.
  • Objective-C utilizza un paradigma di messaggistica (come Smalltalk) in cui è possibile inviare "messaggi" agli oggetti tramite metodi / selettori.
  • Objective-C ti farà felicemente inviare un messaggio a nil, a differenza di C ++ che andrà in crash se provi a chiamare una funzione membro dinullptr
  • Objective-C consente l'invio dinamico, consentendo alla classe che risponde a un messaggio di essere determinata in fase di esecuzione, a differenza di C ++ in cui l'oggetto su cui viene invocato un metodo deve essere conosciuto al momento della compilazione (vedere il commento di Wilhelmtell di seguito). Questo è legato al punto precedente.
  • Objective-C consente l'autogenerazione di accessori per variabili membro usando "proprietà".
  • Objective-C consente di assegnare selfe consente agli inizializzatori di classe (simili ai costruttori) di restituire una classe completamente diversa, se lo si desidera. Contrariamente a C ++, dove se si crea una nuova istanza di una classe (implicitamente nello stack o esplicitamente attraverso new), è garantito che sia del tipo specificato in origine.
  • Allo stesso modo, in Objective-C altre classi possono anche modificare dinamicamente una classe target in fase di esecuzione per intercettare le chiamate al metodo.
  • Objective-C manca della funzionalità dello spazio dei nomi di C ++.
  • Objective-C manca di un equivalente ai riferimenti C ++.
  • Objective-C manca di modelli, preferendo (ad esempio) invece di consentire una digitazione debole nei contenitori.
  • Objective-C non consente il sovraccarico implicito del metodo, ma C ++ lo fa. Cioè, in C ++ int foo (void)e int foo (int)definire un sovraccarico implicito del metodo foo, ma per ottenere lo stesso in Objective-C sono necessari i sovraccarichi espliciti - (int) fooe - (int) foo:(int) intParam. Ciò è dovuto al fatto che i parametri nominati di Objective-C sono funzionalmente equivalenti alla modifica del nome di C ++.
  • Objective-C consentirà felicemente a un metodo e una variabile di condividere lo stesso nome, a differenza di C ++ che in genere avrà adattamenti. Immagino che questo abbia a che fare con Objective-C usando selettori anziché puntatori a funzioni, e quindi i nomi dei metodi non hanno effettivamente un "valore".
  • Objective-C non consente la creazione di oggetti nello stack: tutti gli oggetti devono essere allocati dall'heap (sia esplicitamente con un allocmessaggio, sia implicitamente in un metodo factory appropriato).
  • Come C ++, Objective-C ha sia strutture che classi. Tuttavia, laddove in C ++ vengono trattati quasi esattamente allo stesso modo, in Objective-C vengono trattati in modo completamente diverso: ad esempio, è possibile creare strutture nello stack.

Secondo me, probabilmente la differenza più grande è la sintassi. Puoi ottenere sostanzialmente le stesse cose in entrambe le lingue, ma secondo me la sintassi C ++ è più semplice mentre alcune delle funzionalità di Objective-C rendono più semplici determinate attività (come la progettazione della GUI) grazie al dispacciamento dinamico.

Probabilmente anche molte altre cose che mi sono perso, aggiornerò con qualsiasi altra cosa a cui penso. A parte questo, consiglio vivamente la guida che LiraNuna ti ha indicato. Per inciso, un altro sito di interesse potrebbe essere questo .

Devo anche sottolineare che sto appena iniziando a imparare Objective-C da solo, e come molto di quanto sopra potrebbe non essere del tutto corretto o completo - mi scuso se è così, e accolgo con favore suggerimenti per il miglioramento.

EDIT: aggiornato per affrontare i punti sollevati nei seguenti commenti, aggiunto alcuni altri elementi all'elenco.


8
Elenco decente; una correzione. Non sono "parametri nominati", ma "parametri interfogliati". Nomi e "argomenti di parole chiave" portano alla confusione nel pensare che alcuni sottoinsiemi del nome del metodo possano essere omessi. Non può.
bbum

7
Hai dimenticato di inserire la differenza più importante: Object-C utilizza l'invio dinamico, mentre C ++ utilizza l'invio statico. In altre parole, il codice compilato da un compilatore Objective-C avrà la classe responsabile della risposta a un messaggio determinato in fase di esecuzione; il codice compilato da un compilatore C ++ ha queste informazioni calcolate e compilate su compiletime.
Wilhelmtell,

9
@wilhelmtell: il compilatore C ++ conosce solo la superclasse al momento della compilazione. In fase di esecuzione la classe effettiva potrebbe essere qualsiasi discendente. Questa è anche una forma di invio dinamico, ma non la stessa di quella usata nell'Obiettivo C. Basta stare attenti a questi termini tecnici!
Norman Ramsey

5
+1 Buona lista. Tuttavia, Objective-C utilizza anche void*e NULL, non solo per gli oggetti. È possibile utilizzare qualsiasi puntatore di tipo C in Obj-C e molte chiamate API in realtà passano o restituiscono valori per riferimento, nel qual caso NULLviene utilizzata di frequente.
Quinn Taylor,

3
@wilhelmtell - Non so nulla sull'obiettivo-C, ma in C ++ PUOI dinamicamente avere una classe diversa per rispondere a una chiamata di funzione, ma dovresti avere qualcosa come una matrice di puntatori a una classe base, quindi le classi ATTUALI che si "appendono" fuori di esso. Mentre tutte le classi devono essere sottoclassi, una chiamata al metodo chiamerà metodi diversi a seconda della classe, in fase di esecuzione.
Kevin Anderson,

33

Sebbene siano entrambi radicati in C, sono due lingue completamente diverse.

Una grande differenza è che Objective-C è focalizzato sulle decisioni di runtime per il dispacciamento e dipende fortemente dalla sua libreria di runtime per gestire l'ereditarietà e il polimorfismo, mentre in C ++ il focus di solito si basa su decisioni statiche, di compilazione, di tempo.

Per quanto riguarda le librerie, è possibile utilizzare le librerie C semplici in entrambe le lingue, ma le loro librerie native sono completamente diverse.

È interessante notare che è possibile mescolare entrambe le lingue (con alcune limitazioni). Il risultato si chiama Objective-C ++ .


collegamento aggiornato: Objective-C ++
IcyIcicle il

6

Sono completamente diversi. Obiettivo C ha più in comune con Smalltalk che con C ++ (beh, a parte la sintassi, davvero).


6

In cima alla mia testa:

  1. Stili: Obj-C è dinamico, C ++ è in genere statico
  2. Sebbene siano entrambi OOP, sono certo che le soluzioni sarebbero diverse.
  3. Modello a oggetti diversi (C ++ è limitato dal suo sistema di tipi in fase di compilazione).

Per me, la differenza più grande è il sistema modello. Obj-C ti consente di fare messaggistica e introspezione, ma C ++ ha i modelli sempre così potenti.

Ognuno ha i suoi punti di forza.


5

Come altri hanno già detto, Objective-C è molto più dinamico in termini di come pensa agli oggetti rispetto al regno abbastanza statico di C ++.

Objective-C, essendo nel lignaggio Smalltalk di linguaggi orientati agli oggetti, ha un concetto di oggetti che è molto simile a quello di Java, Python e altri linguaggi "standard" non orientati agli oggetti. Un sacco di invio dinamico, nessun sovraccarico dell'operatore, invio di messaggi in giro.

Il C ++ è il suo strano animale; per lo più ha saltato la parte Smalltalk dell'albero genealogico. In un certo senso, ha un buon sistema di moduli con supporto per l'ereditarietà che sembra essere in grado di essere utilizzato per la programmazione orientata agli oggetti. Le cose sono molto più statiche (i metodi sostituibili non sono quelli predefiniti, ad esempio).


4

Objective-C è un superset più perfetto di C. In C e void*è consentito il cast implicito da un puntatore a struttura.

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

Il C ++ non verrà compilato a meno che il voidpuntatore non sia esplicitamente cast:

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

La rilevanza di questo per la programmazione giornaliera è zero, solo un fatto curioso.


Il secondo esempio non è il codice C ++. È il codice C che ti ha dato un errore quando hai provato a compilarlo con il compilatore C ++. Se vuoi che il vecchio C ++ sia il più vicino all'originale, potresti scrivere Foo* bar = reinterpret_cast< Foo* >(malloc(sizeof(Foo));quindi potresti usare il costruttore inplace .. Ma ad oggi il suo C ++ moderno è più simile al auto bar = new Foo(constructorArg);vero non hai bisogno di malloc e di entrambi i callic, puoi usare std::vector::reserveestd::vector::emplace_mack
xakepp35

3

Obj-C ha capacità molto più dinamiche nel linguaggio stesso, mentre C ++ è più focalizzato sulle capacità di compilazione con alcune funzionalità dinamiche.

In, il polimorfismo parametrico C ++ viene verificato in fase di compilazione, mentre in Obj-C, il polimorfismo parametrico viene ottenuto tramite invio dinamico e non viene verificato in fase di compilazione.

Obj-C è di natura molto dinamica. È possibile aggiungere metodi a una classe durante il runtime. Inoltre, dispone di introspezione in fase di esecuzione per esaminare le classi. In C ++, la definizione di classe non può cambiare e tutta l'introspezione deve essere fatta in fase di compilazione. Sebbene, la natura dinamica di Obj-C potrebbe essere raggiunta in C ++ usando una mappa di funzioni (o qualcosa del genere), è ancora più dettagliata che in Obj-C.

In C ++, ci sono molti più controlli che possono essere fatti in fase di compilazione. Ad esempio, utilizzando un tipo di variante (come un'unione) il compilatore può imporre che tutti i casi vengano scritti o gestiti. Quindi non dimenticare di gestire i casi limite di un problema. Tuttavia, tutti questi controlli hanno un prezzo durante la compilazione. Obj-C è molto più veloce nella compilazione rispetto a C ++.


3
Se hai intenzione di parlare di prezzi, sii onesto! Al contrario, Obj-C è molto più lento nel runtime delle chiamate a metodi dinamici rispetto a C ++. E direi che la velocità di compilazione è una banalità relativa rispetto alla velocità di runtime. Sono sicuro che Obj-C offre molti vantaggi grazie alla sua spedizione più dinamica, ma c'è un compromesso lì.
underscore_d

1
È vero, c'è un compromesso tra tempo di esecuzione e costo del tempo di compilazione. Tuttavia, il tempo di compilazione non è sempre banale. L'uso di pesanti librerie di metaprogrammazione ed EDSL in C ++ (come Boost.Spirit) può avere un effetto drastico sui tempi di compilazione, producendo al contempo un codice molto veloce in fase di esecuzione.
Paul Fultz II

1
Certo, stavo semplificando eccessivamente rispetto al POV di codebase più semplici ... Con codebase molto complesse, ricompilare per testare piccole modifiche potrebbe rendere lo sviluppo molto noioso, il che non è una banalità. Ma è qualcosa che possiamo davvero confrontare tra i due? Tali librerie, così dipendenti dalle funzionalità di compilazione C ++, possono in qualche modo essere reinventate in Objective-C e mostrate per compilare più velocemente? vale a dire la frase "Obj-C è molto più veloce nella compilazione rispetto a C ++" si riferisce a basi di codice equivalenti per le quali è possibile misurare uno speedup replicabile? Altrimenti stiamo confrontando il tempo impiegato per coltivare mele e arance.
underscore_d
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.