Qual è la differenza tra l'operatore punto (.) E -> in C++?Qual è la differenza tra l'operatore punto (.) E -> in C++?
risposta
L'operatore .
è per l'accesso diretto agli utenti.
object.Field
La freccia dereferenzia un puntatore in modo da poter accedere all'oggetto/memoria che sta puntando
pClass->Field
L'operatore freccia è come dot, tranne che dereferenzia un puntatore prima. foo.bar()
chiama il metodo bar()
sull'oggetto foo
, foo->bar
chiama il metodo bar
sull'oggetto puntato dal puntatore foo
.
-> utilizzare quando si ha il puntatore . utilizzare quando si ha struttura (classe) quando si desidera utilizzare l'attributo punto appartenente alla struttura. structure.attribute
quando vogliono punto di attribuire che hanno refference alla memoria con l'uso del puntatore ->:
pointer->method;
or same as:
(*pointer).method
Il bersaglio. Il punto funziona sugli oggetti; la freccia funziona sui puntatori agli oggetti.
std::string str("foo");
std::string * pstr = new std::string("foo");
str.size();
pstr->size();
L'operatore di punti non può essere sovraccaricato, l'operatore di freccia può essere sovraccaricato. L'operatore di frecce è generalmente pensato per essere applicato a puntatori (o oggetti che si comportano come puntatori, come puntatori intelligenti). L'operatore punto non può essere applicato ai puntatori.
EDIT Quando applicato all'operatore puntatore freccia equivale ad applicare operatore punto per pointee (campo ptr-> è equivalente a (* ptr) .field)
Sebbene l'operatore di riferimento indiretto ('* foo') possa essere sovraccaricato – user
foo->bar()
è lo stesso (*foo).bar()
.
Le parentesi qui sopra sono necessarie a causa della forza di legame degli operatori *
e .
.
*foo.bar()
non avrebbe funzionato perché Dot (.
) operatore viene valutata per prima (vedi operator precedence)
The Dot (.
) operatore non può essere sovraccaricato, freccia (->
) operatore può essere sovraccaricato.
L'operatore Punto (.
) non può essere applicato ai puntatori.
Vedi anche: What is the arrow operator (->) synonym for in C++?
Si noti che questo è solo per i puntatori raw. Per i tipi di classe che sovraccaricano l'operatore, ha alcune altre proprietà interessanti ... –
non dà fastidio che -> è un operatore di drill down, e quindi se sovraccaricato non è equivalente a membro dell'oggetto derefenced (* boo) .foo? come se boo-> foo possa essere sovraccaricato per restituire un oggetto proxy intermedio che ha un membro foo diverso da quello nella classe di origine. Non affermerebbe ((* boo) .foo == boo-> foo) fallire. È vero che si dovrebbe essere cauti poiché gli elfi C++ possono essere in agguato nell'oscurità. – g24l
pSomething->someMember
è equivalente a
(*pSomething).someMember
E 'semplice, ogni volta che vedi
x->y
sanno che è la stessa di
(*x).y
Tranne quando non lo è, come quando -> è sovraccarico. – jmtd
Quando sovraccarichi -> dovresti anche sovraccaricare * tale da mantenere questa relazione. Fare altrimenti introdurrà ogni sorta di confusione comunque. –
Il. L'operatore (punto) viene in genere utilizzato per ottenere un campo/chiamare un metodo da un'istanza di classe (o un campo/metodo statico di una classe).
p.myField, p.myMethod() - p esempio di una classe
The -> (freccia) viene utilizzato per ottenere un campo/chiamare un metodo dal contenuto puntato dalla classe.
p-> myField, p-> myMethod() - p punta a una classe
Nota che l'operatore -> non può essere utilizzato per certe cose, per esempio, l'accesso dell'operatore [].
#include <vector>
int main()
{
std::vector<int> iVec;
iVec.push_back(42);
std::vector<int>* iVecPtr = &iVec;
//int i = iVecPtr->[0]; // Does not compile
int i = (*iVecPtr)[0]; // Compiles.
}
Chiaramente no. Perché "foo->" non significa "(* foo)". Significa "(* foo).". Inoltre non può essere utilizzato per addizione, sottrazione ...;) – jmtd
Non vedo come sia rilevante. membro [0] non significa nulla, tuttavia lo zucchero sintattico lo trasforma in member.operator [] (0) se applicabile. È interessante notare che -> non ti permetterà di fare ciò che la maggior parte delle persone si aspetta di poter fare. – gparent
riguardo a quell'operatore, intendo. – gparent
L'-> è lo zucchero semplicemente sintattico per un dereference puntatore,
Come altri hanno detto:
pointer-> metodo();
è un metodo semplice per dire:
(* puntatore) .method();
Per ulteriori puntatore divertente, controlla Binky, e la sua bacchetta magica di dereferenziazione:
per un puntatore, si potrebbe utilizzare
*pointervariable.foo
Ma l'operatore .
ha una maggiore precedenza rispetto all'operatore *
, quindi viene valutato prima .
. Quindi abbiamo bisogno di forzare questo con parentesi:
(*pointervariable).foo
Ma scrivendo la (s ') per tutto il tempo è dura, così hanno sviluppato ->
come una scorciatoia per dire la stessa cosa. Se si accede a una proprietà di un oggetto o riferimento a un oggetto, utilizzare .
Se si accede a una proprietà di un oggetto tramite un puntatore, utilizzare ->
La differenza più semplice tra i due è che "->" dereferenze un puntatore prima va a vedere quali campi degli oggetti, funzione ecc. mentre "." non prima di tutto. Usa "->" quando hai un puntatore a un oggetto e usa "." quando lavori con l'istanza reale di un oggetto.
Un altro modo equivalente per risolvere il problema potrebbe essere quello di utilizzare prima il dereferenziazione "*" sul puntatore e quindi utilizzare semplicemente ".". Saltiamo middleman usando "->".
Ci sono altre differenze, ma le altre risposte lo hanno ampiamente trattato.
Se si dispone di uno sfondo in Java, questo potrebbe confondervi, poiché in Java tutto è puntatori. Ciò significa che non c'è motivo di avere un simbolo che non derifera prima il puntatore. In C++ però devi essere un po 'più attento a ricordare cosa è e cosa non è un puntatore, e potrebbe essere una buona idea etichettarlo con il prefisso "p_" o semplicemente "p".
L'operatore -> viene utilizzato quando si lavora con un puntatore e il punto viene utilizzato in altro modo. Quindi, se abbiamo una classe struct come:
struct class{ int num_students; int yr_grad; };
e abbiamo un esempio di una classe * curr_class (puntatore di classe), quindi per ottenere l'accesso al numero di studenti che avremmo fatto
cout << curr_class->num_students << endl;
nel caso in cui abbiamo avuto un oggetto di classe semplice, dire class_2016, faremmo
cout << class_2016.num_students << endl;
per il puntatore alla classe operatore -> è equivalente a
(*obj).mem_var
Nota: Per una classe, il modo per accedere alle funzioni membro della classe sarà anche nello stesso modo
E se la cosa non è un puntatore? – juanchopanza