Cosa posso usare al posto dell'operatore freccia, `->`?


112

Qual è il ->sinonimo dell'operatore freccia ( )?

Risposte:


148

Le due espressioni seguenti sono equivalenti:

a->b

(*a).b

(soggetto al sovraccarico dell'operatore, come menziona Konrad, ma è insolito).


9
I problemi di sovraccarico sono molto meno insoliti di quanto pensi. Non molto tempo fa, gli implementatori STL avevano alcun overload ->dell'operatore per alcuni tipi di iteratori modo dovuto all'uso *.. Molte biblioteche le definiscono in modo incoerente. Diventa davvero fastidioso quando lavori con i modelli e non conosci il tipo preciso.
Konrad Rudolph

1
puoi anche fare al a[0].bposto di (*a).b. Ma non sarebbe così adeguatamente strutturato.
Sellorio

2
Ragazzi, dopo molti anni di programmazione c #, tornare a c ++ non è solo faticoso dal punto di vista cognitivo, la sintassi c ++ è semplicemente brutta e schifosa. Ho voglia di fare la doccia dopo averlo usato. I programmi scritti in c e c ++ incoraggiano solo una cattiva programmazione. Apple, pre-unix, ha lottato per rendere il linguaggio carino come Pascal.
ATL_DEV

@ATL_DEV Direi che molte delle cose brutte non sono più considerate idiomatiche, ma sfortunatamente ciò non significa che puoi permetterti di non averne familiarità come programmatore C ++ praticante. Anche il percorso sintatticamente piacevole spesso non è il percorso semanticamente bello, ma anche questo è migliorato non peggiore. Ma poi di nuovo ho la sindrome di Stoccolma C ++.
Tim Seguine

@TimSeguine Se vuoi vedere del codice carino, guarda la documentazione all'interno del Macintosh. Penso che abbiano inventato CamelCase. Nomi di variabili molto descrittivi e codice elegantemente formattato. Sono riusciti a rendere il loro codice C successivo stupendo quasi quanto il loro precedente codice Pascal.
ATL_DEV

70

a->bè generalmente sinonimo di (*a).b. Le parentesi qui sono necessarie a causa della forza vincolante degli operatori *e .: *a.bnon funzionerebbe perché si .lega più forte e viene eseguita per prima. Questo è quindi equivalente a *(a.b).

Attenzione al sovraccarico, però: poiché entrambi ->e *possono essere sovraccaricati, il loro significato può differire drasticamente.


1
Con la binding strengthprecedenza degli operatori? se no qual è la differenza tra i due?
Vishnuprasanth

1
@Vizkrig Sì, i due termini sono usati in modo intercambiabile (anche se "precedenza degli operatori" sembra essere molto più frequente, almeno negli ultimi anni).
Konrad Rudolph

45

Il linguaggio C ++ definisce l'operatore freccia ( ->) come sinonimo per dereferenziare un puntatore e quindi utilizzare l' .operatore -per quell'indirizzo.

Per esempio:

Se si dispone di un un oggetto, anObjecte un puntatore, aPointer:

SomeClass anObject = new SomeClass();
SomeClass *aPointer = &anObject;

Per poter utilizzare uno dei metodi degli oggetti, dereferenziare il puntatore ed eseguire una chiamata al metodo su quell'indirizzo:

(*aPointer).method();

Che potrebbe essere scritto con l'operatore freccia:

aPointer->method();

Il motivo principale dell'esistenza dell'operatore freccia è che accorcia la digitazione di un'attività molto comune ed è anche un po 'facile dimenticare le parentesi attorno alla dereferenziazione del puntatore. Se hai dimenticato le parentesi, l'operatore.-Si legherà più forte di * -operator e farà eseguire il nostro esempio come:

*(aPointer.method()); // Not our intention!

Alcune delle altre risposte hanno anche menzionato sia che gli operatori C ++ possono essere sovraccarichi sia che non sono così comuni.


8
new SomeClass()restituisce un puntatore ( SomeClass *), non l' SomeClassoggetto. E inizi con la dichiarazione anObjecte aPointerma stai usando in pseguito.
musiphil

nel complesso questa spiegazione è teoricamente molto azzeccata, solo il cambio di oggetti la rende un po 'contorta. Ma il processo è meglio descritto
Code Man

17

In C ++ 0x, l'operatore ottiene un secondo significato, che indica il tipo restituito di una funzione o di un'espressione lambda

auto f() -> int; // "->" means "returns ..."

1
Tecnicamente la macchiettatura non è più un "operatore" lì, o no?
Martin Ba

6
@ Martin la maggior parte delle persone usa la parola "operatore" per molte cose che non vengono utilizzate direttamente per calcolare i valori. Come per "::" ("operatore di ambito"). Non so quale sia esattamente il punto di vista dello standard su questo. In senso astratto, si potrebbe vedere "->" come un operatore funzionale che mappa una sequenza di tipi (parametri) su un tipo restituito, come l'operatore haskell, che è scritto anche "->".
Johannes Schaub - litb

6
Mi arrendo! :-P
Martin Ba

2
@ JohannesSchaub-litb: ::è in realtà un operatore, come .o ->, ed è chiamato "operatore di risoluzione dell'ambito" nello standard.
musiphil

13

Lo leggo principalmente da destra a sinistra e chiamo "in"

foo->bar->baz = qux->croak

diventa:

"baz in bar in foo diventa gracchiare in qux."


1

-> viene utilizzato quando si accede ai dati a cui si ha un puntatore.

Ad esempio, potresti creare un puntatore ptr a una variabile di tipo int intVar in questo modo:

int* prt = &intVar;

È quindi possibile utilizzare una funzione, come foo, su di essa solo dereferenziando quel puntatore - per chiamare la funzione sulla variabile a cui punta il puntatore, piuttosto che sul valore numerico della posizione di memoria di quella variabile:

(*ptr).foo();

Senza le parentesi qui, il compilatore lo capirebbe come *(ptr.foo())dovuto alla precedenza degli operatori che non è ciò che vogliamo.

In realtà è proprio come scrivere

ptr->foo();

Poiché ->dereferenzia quel puntatore, e così chiama la funzione foo()sulla variabile a cui punta il puntatore per noi.

Allo stesso modo, possiamo usare ->per accedere o impostare un membro di una classe:

myClass* ptr = &myClassMember;
ptr->myClassVar = 2; 

0

È possibile utilizzare -> per definire una funzione.

auto fun() -> int
{
return 100;
}

Non è un lambda. È davvero una funzione. "->" indica il tipo di ritorno della funzione.

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.