operator[][] ??



  • Hallo!
    Also ich bin noch recht neu in der C++ Programmierung und
    bin auch ein Problem gestossen.

    Ich wollte, zum testen und verfestigen meines bisher erworbenen wissens,
    ein kleines TicTacToe Konsolenspiel schreiben.
    Jetzt hab ich mir überlegt wie ich das am klügsten mit dem Feld mache.
    Ein 2 Dimensionales Array? Naja das ist zu kompliziert und unkonfortabel.
    Da ich Java gewohnt bin hab ich sofort an eine Klasse gedacht.
    In der wird das Spielfeld als einfaches Array gespeichert + Grössen angabe
    und ich dachte mir es wäre komfortabel so darauf zuzugreifen:
    feldObjekt[i][i2]

    Jetzt hab ich aber recht wenig Erfahrung im überladen von Operatoren. Im Stroustrup hab ich zwar gesehen wie das überladen von [] geht, aber wie mache ich ein [][] ?? Diesen Operator als Operator selbst gibt es ja glaub ich nicht und ich weiss nciht wie ich den Operator schreiben soll, damit dass so funktioniert.

    Da müsste es ja praktisch 2 versionen geben, einen der per Index eine Zeile als Array zurück liefert und einen der davon dann die "Spalte" zurück gibt.

    Hm, ich glaub ich habe meine Idee etwas konfus und vlt. missverständlich ausgedrückt.
    Aber vielleicht gibt es ja trotzdem jemanden der mir helfen kann 🙂

    Danke schon mal,
    MFG Painkiller



  • Naja - du kannst entweder operator[] eine Struktur zurückgeben lassen, die ebenfalls operator[] unterstützt (wie in std::vector<std::vector<foo> >), oder du kannst operator()(int, int) überladen. Das sähe dann so aus:

    class feld {
    public:
      int &operator()(int x, int y) { return m_feld[x][y]; }
    
    private:
      int m_feld[3][3];
    };
    
    // ...
    
    feld foo;
    foo(0, 1) = 0;
    


  • Wow hier bekommt man ja schnell Antwort 😃

    Also das mit den runden Klammern sieht irgendwie ungewohnt aus 😕
    Hmm, so gesehen könnte ich ja auch einen operator[](int, int) machen, oder?
    Also diese Variante wäre weniger Arbeit, die andere wäre gewohnter.
    Da es ja ums lernen geht sollte ich den Aufwand nicht scheuen.
    Naja, ich schlaf mal drüber 😃 😃

    Danke nochmal,
    MFG Painkiller



  • Nein, einen operator[](int, int) gibt es nicht.



  • Painkiller schrieb:

    Da müsste es ja praktisch 2 versionen geben, einen der per Index eine Zeile als Array zurück liefert und einen der davon dann die "Spalte" zurück gibt.

    nein, muss es nicht.

    #include <iostream>
    #include <cstddef>
    
    class Bar
    {
     public:
        const size_t operator[] (size_t i) const
        {
            std::cout << "Bar::op[]\n";
            return i;
        }
    };
    
    class Foo
    {
     public:
        Foo() 
        {
            b_ = new Bar[5];
        }      
    
        const Bar operator[] (size_t i) const
        {
            std::cout << "Foo::op[]\n";
            return b_[i % 5]; // nur zur sicherheit mod 5
        }    
    
     private:
        Bar* b_;
    };
    
    int main()
    {
        Foo f;
        size_t i = f[3][3];
    
        return 0;
    }
    

    beim zweiten zugriff, benutzt du schon den op[] des angesprochenen objektes und nicht den op[], des containers.

    mfg



  • Ja aber das interne Attribut ist ein Array und kein Objekt. Es wäre overhead jetzt noch eine Klasse zu schreibe nur um das Array zu kapseln.

    Hm, vielleicht ist es am einfachsten eine getter Methode zu schreiben 0_o
    Das ist zwar ein bisschen lowtech, und ich glaub manche finden das "unelegant",
    aber es ist glaub ich am praktischsten 😕



  • @painkiller: 😕 😕
    Du brauchst doch eigentlich nur ein Template für eine Matrix, könntest es sogar auf eine quadratische reduzieren und eigentlich bräuchtest du auch kein template, aber weil's so schön ist..
    hier ein Anfang:

    template < typename T > 
    //oder eben: template< class T >
    class Matrix{
     private:	
      unsigned int nRows;
      unsigned int nCols;
      T ** elem;
     public:
      //....
      const T * operator[](unsigned int)const;
      T * operator[](unsigned int);
    };
    template< class T >
    const T * Matrix<T>::operator[](unsigned int idx)const{ 
        //prüfen, ob idx innerhalb gültigen Wertebereich, ggf exception werfen  
      return elem[idx]; 
    }
    template< class T >
    T * Matrix<T>::operator[](unsigned int idx){ 
      //prüfen, ob idx innerhalb gültigen Wertebereich, ggf exception werfen
      return elem[idx]; 
    }
    


  • 😮 😮

    öhm, ich will doch nur ein kleines TicTacToe programmieren. Ausserdem bin ich im Stroustrup erst beim Kaptiel Operatoren Überladen, Templates kommt noch x)



  • ein template ist nicht anderes (wie der name schon sagt) als eine schablone. es steht für einen datentyp den du selbst bestimmen und ändern kannst.

    ein kleines beispiel:

    template <typename T>
    T add(T eingabe1, eingabe2)
    {
        T ausgabe = eingabe1 + eingabe2;
        return ausgabe;
    }
    

    und das T kann nun für (fast) alles stehen:
    -int
    -double
    -string
    -etc.pp


  • Mod

    mit arrays funktioniert das genauso

    class Foo
    {
    public:
        // c'tor etc.       
        const row& operator[] (size_t i) const { return bar[i]; }
        row& operator[] (size_t i) { return bar[i]; }
    
    private:
        int bar[3][3];
        typedef int row[3];
    };
    


  • [cpp]class foo
    {
    private:
    int bar[5][6];
    public:
    foo(){for(unsigned i=0,j;i<5;++i)for(j=0;j<6;++j)bar[i][j]=ij;};
    int
    operator[](std::size_t index){return bar[index];};
    //kann man auch int[6] op... schreiben?
    };



  • class foo 
    { 
    private: 
    int bar[5][6]; 
    public: 
    foo(){for(unsigned i=0,j;i<5;++i)for(j=0;j<6;++j)bar[i][j]=i*j;}; 
    int* operator[](std::size_t index){return bar[index];}; 
    //kann man auch int[6] op... schreiben? 
    };
    

    shit, hab mich schon so ans editing gewöhnt...



  • @Painkiller
    Irgendwie versteh ich dein Problem nicht so ganz. Ein "2-dimensionales Array" ist im Grunde auch nichts anderes als ein normales Array, mit der Besonderheit, dass jedes Element wiederum ein Array ist. Du implementierst 'operator []' also genau wie bei einfachen Arrays. Schau dir camper's Code an, dann verstehst du was ich meine.



  • Painkiller schrieb:

    Ja aber das interne Attribut ist ein Array und kein Objekt. Es wäre overhead jetzt noch eine Klasse zu schreibe nur um das Array zu kapseln.

    das objekt ist nur zur operatorüberladung da, damit ich eine ausgabe produzieren kann. im endeffekt ist es dasselbe.

    mfg



  • // Zu spät


Anmelden zum Antworten