Risposte:
Le due espressioni seguenti sono equivalenti:
a->b
(*a).b
(soggetto al sovraccarico dell'operatore, come menziona Konrad, ma è insolito).
a[0].b
posto di (*a).b
. Ma non sarebbe così adeguatamente strutturato.
a->b
è generalmente sinonimo di (*a).b
. Le parentesi qui sono necessarie a causa della forza vincolante degli operatori *
e .
: *a.b
non 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.
binding strength
precedenza degli operatori? se no qual è la differenza tra i due?
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, anObject
e 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.
new SomeClass()
restituisce un puntatore ( SomeClass *
), non l' SomeClass
oggetto. E inizi con la dichiarazione anObject
e aPointer
ma stai usando in p
seguito.
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 ..."
::
è in realtà un operatore, come .
o ->
, ed è chiamato "operatore di risoluzione dell'ambito" nello standard.
->
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;
->
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.