2016-01-04 34 views
8

Ho una classe template Array:C++ - di sovraccarico [] operatore

template <class T=int, int SIZE=10> 
class Array { 
    T TheArray[SIZE]; 
public: 
    void Initialize() { 
     for (int idx=0; idx < SIZE; idx++) { 
      TheArray[idx] = T(); 
     } 
    } 

    T& operator [](int idx) { 
     return TheArray[idx]; 
    } 

    T operator [](int idx) const { 
     return TheArray[idx]; 
    } 
} 

ho alcune domande sul operatore [] sovraccarico (ho trovato questo esempio sulla rete).

Capisco che T& operator [](int idx) restituisca il riferimento al valore di matrice con l'indice idx e che T operator [](int idx) const restituisca il suo valore. Tuttavia, non sono sicuro in quale caso il riferimento o il valore verrà restituito utilizzando l'operatore [].

Inoltre, se cambio T operator [](int idx) const ->T operator [](int idx), il compilatore si lamenta. Perché? Posso capire che il compilatore si lamenta perché solo il tipo restituito è diverso, ma perché non si lamenta quando viene aggiunto const? Questo significa solo che non vengono modificati gli interni della classe, giusto?

ho cercato di eseguire il debug di questa piccola applicazione principale:

int main() { 
    int val; 
    Array<> intArray; 

    intArray.Initialize(); 
    val = intArray[1]; 
    printf("%d", intArray[1]); 
    intArray[1] = 5; 
} 

E ogni volta T& operator [](int idx) è chiamato. Perché?

Grazie in anticipo.

+0

In una nota a margine, preferire i costruttori appropriati a funzioni come 'initialize'. C++ ti offre uno strumento perfetto per l'inizializzazione degli oggetti e si chiama costruttore. – SergeyA

risposta

12

Il sovraccarico operator[] verrà selezionato in base allo const -qualificazione dell'oggetto su cui viene chiamato.

Array<> intArray; 
intArray[1]; //calls T& operator[] 

const Array<> constArray; 
constArray[1]; //calls T operator[] 

Se si rimuove il const da T operator[], si ottiene un errore perché le funzioni membro non possono avere gli stessi const -qualification e parametri in quanto non vi sarebbe alcun modo per selezionare tra di loro.

12

Per prima cosa, vedere [] come zucchero sintattico per chiamare this->operator[].

La versione const sarà chiamato se this è un puntatore const, altrimenti la non versione const sarà chiamato.

Per andare avanti, è necessario utilizzare const T& operator [](int idx) const {, ad esempio la versione const restituisce un riferimento const. Ciò salverà il sovraccarico di una copia profonda.

Infine, l'const -nessa di una funzione è parte della sua firma. Ciò consente di sovraccaricare basato su const -ness. Altrimenti non è possibile avere le due versioni di operator[].

+1

Chiamerei anche restituire un riferimento temporaneo invece di const un odore/bug di progettazione qui, in quanto porta a incongruenze, ovvero: [perché non posso usare gli argomenti const in memcpy?] (Http://stackoverflow.com/q/ 17669913/1942027) Si dovrebbe orientarsi sulla libreria standard per prevenire comportamenti sorprendenti e ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector/operator_at) restituisce un riferimento const . –