L'operatore di accesso per indice operator[] è un operatore sovraccaricabile in C++ per fornire la sintassi di indicizzazione degli oggetti dei contenitori personalizzati (ad esempio, come gli array).
Storia della questione:
Nel linguaggio C, e successivamente in C++, l'operatore [] consentiva di accedere rapidamente e facilmente agli elementi di un array per indice. Tuttavia, con l'aumento della popolarità delle classi contenitore, è emersa la necessità di trasferire la stessa sintassi ai tipi di dati personalizzati.
Problema:
La progettazione corretta degli operatori di accesso per indice è associata a questioni di costanza, sicurezza di accesso fuori dai limiti (out-of-bounds), scelta del valore restituito e garanzia di validità del riferimento o puntatore.
Soluzione:
In C++ è possibile sovraccaricare operator[] per le classi, per consentire l'accesso agli elementi per indice e implementare per essi un "comportamento simile a quello degli array". È necessario implementare entrambe le versioni dell'operatore: quella normale (per oggetti non const) e quella const (per oggetti const).
Esempio di codice:
class MyArray { int data[10]; public: int& operator[](size_t index) { return data[index]; } const int& operator[](size_t index) const { return data[index]; } }; MyArray arr; arr[3] = 42; // OK const MyArray& const_arr = arr; int val = const_arr[3]; // OK
Caratteristiche chiave:
.at() nei contenitori standard).È obbligatorio restituire un riferimento da operator[]?
No — ma se si restituisce un valore, la sintassi arr[i] = x; non funzionerà (si copierà invece di assegnare). Per mantenere la semantica abituale del contenitore, di solito si restituisce un riferimento. Se si restituisce un valore, non sarà possibile scrivere in un elemento:
int operator[](size_t idx); // arr[2] = 10; non si compilerà
Deve operator[] controllare i limiti?
Lo standard non lo richiede. L'operatore classico operator[] (come in std::vector) NON effettua tali controlli. Per i controlli, i contenitori standard introducono un metodo separato .at(), che lancia un'eccezione in caso di accesso oltre i limiti dell'indicizzazione.
Può operator[] essere un metodo const?
No — se restituisci un riferimento non const. Tuttavia, è necessario sovraccaricare operator[] per oggetti const e non const affinché il contenitore funzioni in modo intuitivo e sicuro.
Un giovane sviluppatore ha implementato solo la versione non const di operator[], restituendo per valore. Di conseguenza, il contenitore non poteva essere accessibile tramite riferimento const, e qualsiasi tentativo di scrittura funzionava in modo strano — i valori non venivano salvati.
Vantaggi:
Svantaggi:
Nel contenitore MyArray sono state implementate entrambe le versioni di operator[], con restituzione corretta dei riferimenti. Se necessario, è stato aggiunto il metodo at() con controllo dei limiti.
Vantaggi:
Svantaggi: