2016-01-04 15 views
8

ich eine Template-Klasse Array haben:C++ - Überlastung Operator []

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]; 
    } 
} 

Ich habe einige Fragen auf Betreiber [] Überlastung (Ich fand dieses Beispiel auf netto).

Ich verstehe, dass T& operator [](int idx) Verweis auf Array-Wert mit Index idx zurückgibt und dass T operator [](int idx) const seinen Wert zurückgibt. Ich bin mir jedoch nicht sicher, in welchem ​​Fall Referenz oder Wert mit dem Operator [] zurückgegeben wird.

Auch, wenn ich T operator [](int idx) const ändern ->T operator [](int idx), beschwert sich Compiler. Warum das? Ich kann verstehen, dass Compiler beschwert, weil nur Rückgabetyp ist anders, aber warum es nicht beschweren, wenn const hinzugefügt wird? Das bedeutet nur, dass nicht die Klasseneinbauten geändert werden, oder?

Ich habe versucht, diese kleine Haupt-Implementierung zu debuggen:

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

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

Und jedes Mal T& operator [](int idx) genannt wird. Warum?

Vielen Dank im Voraus.

+0

Nebenbei bemerkt, bevorzugen Sie richtige Konstruktoren zu Funktionen wie 'initialize'. C++ bietet Ihnen ein perfektes Werkzeug für die Initialisierung von Objekten und es heißt Konstruktor. – SergeyA

Antwort

12

Die operator[] Überladung wird basierend auf der const -Qualität des Objekts ausgewählt, das Sie aufrufen.

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

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

Wenn Sie die const von T operator[] entfernen, erhalten Sie einen Fehler, weil die Mitgliederfunktionen nicht die gleichen const -qualifikation und Parameter haben kann, da es keine Möglichkeit, zwischen ihnen zu wählen wäre.

12

Erste Sache, betrachten Sie [] als syntaktischen Zucker für den Aufruf this->operator[].

Die const Version aufgerufen wird, wenn this ein const Zeiger ist, sonst die nicht const Version aufgerufen.

Weitergehen, Sie sollten const T& operator [](int idx) const { verwenden, d. H. Die const Version eine const Referenz zurückgeben. Das wird den Overhead einer tiefen Kopie sparen.

Schließlich ist die const -ness einer Funktion Teil seiner Signatur. Dies ermöglicht Ihnen eine Überlastung basierend auf const -ness. Ansonsten könnten Sie die beiden Versionen operator[] nicht haben.

+1

Ich würde sogar einen temporären anstelle eines const-Verweises als Design-Geruch/Fehler bezeichnen, da dies zu Inkonsistenzen führt, zB: [Warum kann ich in memcpy keine konstanten Argumente verwenden?] (Http://stackoverflow.com/q/) 17669913/1942027) Man sollte sich an der Standardbibliothek orientieren, um überraschendes Verhalten zu vermeiden, und ['std :: vector'] (http://en.cppreference.com/w/cpp/container/vector/operator_at) gibt eine const-Referenz zurück . –