Probleme beim Ueberladen von []



  • Hallo! 🙂

    Ich habe ein Problem mit dem Übeladen des []-Operators. Ich habe eine Übungsaufgabe bearbeitet, in der man eine Klass erstellen sollte, die ein Double-Array simuliert- d.h. auch die Addition von Arrays ermöglicht, die Initialisierung eines Arrays mit einem anderen usw.

    Das hat auch alles fast so geklappt nur wenn ich z.B. so einen Ausdruck habe:

    CDoubleArray array;
    array[0] = 1.1;

    Dann meldet der Compiler (logischerweise) einen Fehler, dass ich array[] nichts zuweisen kann. Ich hab den Code mal angefügt und würde mich freuen, wenn mir jmd. etwas dazu sagen könnte, weil ich z.Z. irgendwie ein Brett vor dem Kopf hab 😕

    #include <iostream>
    
    class CDoubleArray {
          private:
                  double *doubleArray;
                  int array_size;
    
          public:
                 CDoubleArray() {}    // Default Konstruktor
    
                 CDoubleArray(int size) {                 //Konstruktor nur mir Größenangabe
                                doubleArray = new double[(size +1)];
                                array_size = size;
                                }
    
                 CDoubleArray(int size, const double *dptr) {               //Konstruktor, welches eine Initialisierung
                                  doubleArray = new double[(size +1)];      //mit einem anderen Array ermöglicht
                                  for (int i=0; (i <= size && dptr[i]);  ++i) {
                                      doubleArray[i] = dptr[i];
                                      }
                                  array_size = size;
                                  }
    
                 ~CDoubleArray() {
                                 // std::cout << "Im Destruktor!\n";
                                 if (*doubleArray) delete[] doubleArray;
                                 }
    
                 int getArraySize() const {
                      return array_size;
                      }
    
                 bool setArraySize(int newsize);
    
                 void operator=(const CDoubleArray &vorbild);
    
                 double operator[](int position) const;
    
                 }; //Ende Class CDoubleArray
    
                 bool CDoubleArray::setArraySize(int newsize) {
                      if (newsize <= array_size) return false;          //Aktion fehlgeschlagen - nichts zu tun
                      double *temp_array = new double[array_size+1];    // Alte Elemente kopieren um altes Array zu löschen
                      for (int z=0; (z <= array_size && doubleArray[z]); ++z) {
                          temp_array[z] = doubleArray[z];
                          }
                      delete[] doubleArray;
                      doubleArray = new double[newsize];                 //neues Array erstellen
    
                      for (int z=0; (z <= array_size && temp_array[z]); ++z) { //Elemente zurückkopieren
                          doubleArray[z] = temp_array[z];
                          }
    
                      delete[] temp_array;
                      array_size = newsize;
    
                      //std::cout << "Array vergroessert!\n";
    
                      return true;                       //Aktion erfolgreich
                      }
    
                 void CDoubleArray::operator=(const CDoubleArray &vorbild) {   //Ermöglicht es Arrays einander zuzuweisen
    
                           if (array_size < vorbild.getArraySize()) {      //Array zu klein? Vergrößern!
                                          setArraySize(vorbild.getArraySize()); 
                                          }
    
                           for (int i=0; ((i <= array_size )&& vorbild[i]);  ++i) {  //Kopiere Elemente
                                      this->doubleArray[i] = vorbild[i];
                                      }                  
                                      }
    
                 double CDoubleArray::operator[](int position) const{    //Überladener []-Operator um Index-Verwendung zu 
                                                                          //ermöglichen
                               return doubleArray[position];       
                               }
    
    //MAIN
    
    int main() {
    
        CDoubleArray First(5);
    
        double array[10] = {1.1, 1.2, 1.3};
    
        std::cout << "First ist " << First.getArraySize() << " Einheiten gross!\n";
    
        CDoubleArray Second(2, array);
    
        std::cout << "Second ist " << Second.getArraySize() << " Einheiten gross!\n";
    
        CDoubleArray Third = Second; 
    
        std::cout << "Third ist " << Third.getArraySize() << " Einheiten gross!\n";
    
        std::cout << "Erstes und zweites Element von Third: " << Third[0] << " " << Third[1] << "\n";
    
        Third.setArraySize(10);
    
        std::cout << "Third ist " << Third.getArraySize() << " Einheiten gross!\n";
    
        return 0;
    }
    

    Das Programm erzeugt folgende (erwartete) Ausabe:

    First ist 2 Einheiten groß
    Second ist 2 Einheiten groß
    Third ist 2 Einheiten groß
    Erstes und zweites Element von Third: 1.1 1.2
    Third ist 10 Einheiten groß

    Ich denke die Aufgabe ist solange noch nicht richtig abgeschlossen, solange ich das CDoubleArray nicht wirklich wie ein Array benutzen kann.
    Eine Zuweisung wie
    First[1] = 1.1;
    sollte also möglich sein.

    Also den =operator für eine Double zu überladen wäre wahrscheinlich der erste Schritt:
    [cpp]void operator=(double double_to_add) {...} [code]
    Aber woher weiß ich, auf welchen Index von "doubleArray" (private: double *doubleArray) ich zugreife?

    Wer noch Zeit hat, dem wäre ich dankbar, wenn er Kritik (bitte konstruktiv 😉 ) an meinem Programmierstil äußern könnte. Man selbst übersieht seine Fehler ja schnell.

    Vielen Dank schonmal



  • Du musst im op[] eine Referenz zurückgeben 😉 So machst Du ja eine Kopie und der Wert kommt nie im Array an.



  • außerdem darf der operator nicht mehr const sein



  • Er darf durchaus const sein, da er das Objekt physikalisch nicht verändert.

    Da man aber ein modifizierbares Handle auf interne Daten rausgibt, ist er logisch gesehen nicht const - und sollte folglich richtig auch nicht const deklariert sein.
    (wenn this const ist, wird double doubleArray* zu double * const doubleArray, nicht const double* doubleArray)

    Da man operator[] aber auch gerne in const-Situationen benutzen möchte, sollte man eine const Variante á la
    const double& operator[]( std::size_t index) const
    hinzufügen.

    Das vielleicht auch noch als Tip an ++Gast: Parameter, die sich auf den Index beziehen, sollten immer std::size_t oder zumindest unsigned sein, da negative Subscripts keinen Sinn machen in deiner Klasse.



  • Danke Leute, ich habs jetzt. Der (Denk-)Fehler war, dass ich ernsthaft glaubte den =-Operator überladen zu müssen 🙄

    Das vielleicht auch noch als Tip an ++Gast: Parameter, die sich auf den Index beziehen, sollten immer std::size_t oder zumindest unsigned sein, da negative Subscripts keinen Sinn machen in deiner Klasse.

    Danke, werde ich umsetzen 🙂


Anmelden zum Antworten