Arbeiten mit Klassen im Heap?



  • Ich habe versucht ein Array im Heap zu speichern. Das Funktionierte dennoch weiß ich jetzt nicht wie ich darauf zugreifen kann. Mit Zeigern hab ich es schon ein paar mal ausprobiertaber nichts klappte. Hier ist ein kleiner Ausschnitt aus dem Quelltext.

    #include <iostream>
    
    class Ship
    {
      public:
         Ship();
         ~Ship();
         char GetShip () const {return itsShip;}
         void SetShip (char ship) {itsShip = ship;}
    
      private:
         char itsShip;
    
    };
    
    int main()
    {
       Ship * pShip = new Ship[4][4];  //Zeile 18
       int Size;
       int Poi;         //Fr die Position am linken Rand.
       int Poj;         //Fr die Position am oberen Rand.
       int mShips;
       int oou;
       bool OOU;
       bool End;
       int Err;       // Zum best„tigen der Eingabe.
       bool Error;    // Geh”rt zu int Err.
    
       cout << "Geben sie die Positionen folgender maáen an:GR™áE UNTEREPOSIT OBEREPOSIT\n";
       cout << "                                              1        0          0\n";
       cout << "Sehen sie sich jetzt das Feld an!\n";
       cout << "   0 1 2 3 \n";
       cout << " 0         \n";
       cout << " 1         \n";
       cout << " 2         \n";
       cout << " 3         \n";
       cout << "Geben sie nun nach dem vorhin genannten Beispiel die Positionen\nder Schiffe an!\n";
    
       for (;;)
       {
          mShips = 0;
    
          for (;mShips < 5;)
          {
             cout << "Die Größe:";
             cin >> Size;
             cout << "\nPosition am linken Rand:";
             cin >> Poi;
             cout << "\nPosition am oberen Rand:";
             cin >> Poj;
             cout << endl;
             if (Poi < 0 || Poi > 4 || Poj < 0 || Poj > 4)
                continue;
    
             switch (Size)
             {
                case 1: Ship[Poi][Poj] = 'S';  //Zeile 57.
                        mShips = mShips + 1;
                        break;
                case 2: OOU = false;
    
                        cout << "\nSoll es waagerecht (0) stehen oder senkrecht (1)?\n";
                        cin >> oou;
    
                        if (oou == 1)
                           OOU = true;
    
                        if (OOU == false && Poj <= 2 && Poj >= 0)
                        {
                           Ship[Poi][Poj] = 'S';   //Zeile 70
                           Ship[Poi][Poj + 1] = 'S';
                        }
                        else
                        {
                           if (OOU == true && Poi <= 2 && Poi >= 0)
                           {
                              Ship[Poi][Poj] = 'S';   //Zeile 77
                              Ship[Poi + 1][Poj] = 'S';
                           }
                           else
                           {
                              cout << "Das Schiff ist für diese Position zu groß, versuch es noch mal.\n";
                              continue;
                           }
                        }
                        if (mShips >= 5)
                        {
                           cout << "Du hast bereits zu viele Schiffe für so ein großes Schiff!\n";
                           continue;
                        }
                        mShips = mShips + 2;
    
                        break;
                case 10: cout << "Das Spiel wird Beendet.\n";
                         End = true;
                         break;
                default: cout << "\nDas Schiff ist zu groß versuch es noch mal.\n";
                         cout << "Du hast noch " << mShips << " Schiffe zur Verfügung.\n";
                         continue;
             }   // Beendet switch
             if (End == true)
                return 0;
             cout << "So sieht das Feld zur Zeit aus.\n";
             cout << "   0 1 2 3\n";
             cout << " 0 "<<Ship[0][0]<<"  "<<Ship[0][1]<<"  "<<Ship[0][2]<<"  "<<Ship[0][3]<<endl;  //Zeile 105
             cout << " 1 "<<Ship[1][0]<<"  "<<Ship[1][1]<<"  "<<Ship[1][2]<<"  "<<Ship[1][3]<<endl;  //Zeile 106
             cout << " 2 "<<Ship[2][0]<<"  "<<Ship[2][1]<<"  "<<Ship[2][2]<<"  "<<Ship[2][3]<<endl;  //Zeile 107
             cout << " 3 "<<Ship[3][0]<<"  "<<Ship[3][1]<<"  "<<Ship[3][2]<<"  "<<Ship[3][3]<<endl;  //Zeile 108
    
             cout << "Sie haben noch " << mShips << " Schiffe zur verfügung!\n";
    
          }   //Für die innere for - Schleife.
          cout << "\nSind sie mit der Eingabe zufrieden? Ja (1) oder Nein (0).\n";
          cin >> Err;
          if (Err == 1)
             Error = true;
    
          if (Error == true)
             break;
       }
    
     return 0;
    }
    

    Der Kompiler gab folgendes aus:Test.cpp: In function 'int main()' :
    Test.cpp:18: initialization to 'Ship ' from 'Ship ()[4]'
    Test.cpp:57: parse error before '['

    Letztere gilt auch für die Zeilen: 70, 77, 105, 106, 107, 108
    Die Zeilen hab ich im Quellcode gekennzeichnet.
    Wie kann ich die Fehler beheben?



  • new Ship[4][4];
    
    der zurueckgegeben typ ist:
    Ship***
    also:
    Ship*** pShip = new Ship[4][4];
    
    Ship[Poi][Poj] = 'S';  //Zeile 57
    Ship ist die klasse nicht die variable
    also:
    ((*pShip)[Poi][Poj]).SetShip('S')
    


  • Die meisten Fehler konnte ich jetzt schon beheben. Dennoch Funktioniert die Zeile:

    Ship*** pShip = new Ship[4][4];
    

    nicht.
    Ich hab auch schon probiert:

    Ship*** pShip = new ((Ship)[4][4]);
    

    Funktionierte aber auch nicht.



  • so funktioniert einfach der C++ new-Operator nicht.

    FAQ



  • Ich kam mit dem FAQ von dir nicht so richtig klar, d.h. ich hab versucht es so zu machen doch der Kompiler gibt mir jetzt nur noch mehr Fehler aus.
    Deshalb versuche ich es jetzt mit einem 1 - Dimensionalen Array. Der Text sieht folgender maßen aus:

    #include <iostream>
    
    class Ship
    {
      public:
         Ship();
         ~Ship();
         char GetShip () const {return itsShip;}
         void SetShip (char ship) {itsShip = ship;}
    
      private:
         char itsShip;
    
    };
    
    int main()
    {
       Ship** pShip = new Ship[16];  //Wir ihr seht ist es nur noch ein 1 - 
                                     //Dimensionales Array (Zeile 18)
       int Size;
       int Poi;         //Fr die Position am linken Rand.
       int Poj;         //Fr die Position am oberen Rand.
       int mShips;
       int oou;
       bool OOU;
       bool End;
       int Err;       // Zum best„tigen der Eingabe.
       bool Error;    // Geh”rt zu int Err.
    
       cout << "Geben sie die Positionen folgender maáen an:GR™áE UNTEREPOSIT OBEREPOSIT\n";
       cout << "                                              1        0          0\n";
       cout << "Sehen sie sich jetzt das Feld an!\n";
       cout << "   0 1 2 3 \n";
       cout << " 0         \n";
       cout << " 1         \n";
       cout << " 2         \n";
       cout << " 3         \n";
       cout << "Geben sie nun nach dem vorhin genannten Beispiel die Positionen\nder Schiffe an!\n";
    
       for (;;)
       {
          mShips = 0;
    
          for (;mShips < 5;)
          {
             cout << "Die Größe:";
             cin >> Size;
             cout << "\nPosition am linken Rand:";
             cin >> Poi;
             cout << "\nPosition am oberen Rand:";
             cin >> Poj;
             cout << endl;
             if (Poi < 0 || Poi > 4 || Poj < 0 || Poj > 4)
                continue;
    
             switch (Size)
             {
                case 1: (*pShip[Poi * Poj]).SetShip('S');  //Zeile 57.
                        mShips = mShips + 1;
                        break;
                case 2: OOU = false;
    
                        cout << "\nSoll es waagerecht (0) stehen oder senkrecht (1)?\n";
                        cin >> oou;
    
                        if (oou == 1)
                           OOU = true;
    
                        if (OOU == false && Poj <= 2 && Poj >= 0)
                        {
                           ((*pShip)[Poi * Poj]).SetShip('S');   //Zeile 70
                           ((*pShip)[Poi * (Poj + 1)]).SetShip('S');
                        }
                        else
                        {
                           if (OOU == true && Poi <= 2 && Poi >= 0)
                           {
                              (*pShip[Poi * Poj]).SetShip('S');   //Zeile 77
                              (*pShip[(Poi + 1) * Poj]).SetShip('S');
                           }
                           else
                           {
                              cout << "Das Schiff ist für diese Position zu groß, versuch es noch mal.\n";
                              continue;
                           }
                        }
                        if (mShips >= 5)
                        {
                           cout << "Du hast bereits zu viele Schiffe für so ein großes Schiff!\n";
                           continue;
                        }
                        mShips = mShips + 2;
    
                        break;
                case 10: cout << "Das Spiel wird Beendet.\n";
                         End = true;
                         break;
                default: cout << "\nDas Schiff ist zu groß versuch es noch mal.\n";
                         cout << "Du hast noch " << mShips << " Schiffe zur Verfügung.\n";
                         continue;
             }   // Beendet switch
             if (End == true)
             {
                delete [] pShip;
                return 0;
             }
             cout << "So sieht das Feld zur Zeit aus.\n";
             cout << "   0 1 2 3\n";
             cout << " 0 "<<(*pShip[0]).GetShip()<<"  "<<(*pShip[1]).GetShip()<<"  "<<(*pShip[2]).GetShip()<<"  "<<(*pShip[3]).GetShip()<<endl;  //Zeile 105
             cout << " 1 "<<(*pShip[4]).GetShip()<<"  "<<(*pShip[5]).GetShip()<<"  "<<(*pShip[6]).GetShip()<<"  "<<(*pShip[7]).GetShip()<<endl;  //Zeile 106
             cout << " 2 "<<(*pShip[8]).GetShip()<<"  "<<(*pShip[9]).GetShip()<<"  "<<(*pShip[10]).GetShip()<<"  "<<(*pShip[11]).GetShip()<<endl;
             cout << " 3 "<<(*pShip[12]).GetShip()<<"  "<<(*pShip[13]).GetShip()<<"  "<<(*pShip[14]).GetShip()<<"  "<<(*pShip[15]).GetShip()<<endl;
    
             cout << "Sie haben noch " << mShips << " Schiffe zur verfügung!\n";
    
          }   //Für die innere for - Schleife.
          cout << "\nSind sie mit der Eingabe zufrieden? Ja (1) oder Nein (0).\n";
          cin >> Err;
          if (Err == 1)
             Error = true;
    
          if (Error == true)
             break;
       }
       delete[] pShip; 
     return 0;
    }
    

    Der Kompiler hat mir trotz dem noch ein paar Fehler ausgegeben. Es waren folgende:
    Test3.cpp: in function 'int main()': //Ich habe die Datei Test3.cpp genannt.
    Test3.cpp:18: initialization to 'Ship **' from 'Ship *'

    Was soll ich jetzt machen? 😕



  • pShip soll Ship* sein.

    Warum verwendest du einmal (*pShip[Poi * Poj]). (richtig) und einmal ((*pShip)[Poi * Poj]). (falsch)? Statt (*pShip). kannst du auch pShip-> schreiben.



  • Der Fehler bezieht sich nur auf die Zeile 18. Also wie soll ich die Zeile 18 umschreiben. Der Rest Funktioniert schon so.
    Ich hab auch schon versucht Zeile 18 so zu schreiben:
    Ship* pShip = new Ship[16];
    Doch dann gibt er mir folgenden Fehler aus:
    Ship[int] for Array substrict:
    Mit dieser bezeichnung weiß ich überhaupt nichts anzufangen!
    Also könnt ihr mir Helfen ohne dass ich den gesamten Text verändern muss?



  • Woher willst du wissen, ob der Rest funktioniert, wenn du's nicht einmal compilieren kannst?

    EDIT: Ship* pShip = new Ship[16]; // Das sollte keinen Fehler machen



  • Das war so gemeint, dass mir der Kompiler keinen weiteren Fehler ausgibt.



  • Also bei mir compiliert das hier ohne Probleme:

    class Ship
    {
      public:
         Ship();
         ~Ship();
         char GetShip () const {return itsShip;}
         void SetShip (char ship) {itsShip = ship;}
    
      private:
         char itsShip;
    
    };
    
    Ship::Ship() {}
    
    int main( int argc, char *argv[] )
    {
       Ship* pShip = new Ship[16];
       return 1;
    };
    

    MZ04 schrieb:

    Der Fehler bezieht sich nur auf die Zeile 18. Also wie soll ich die Zeile 18 umschreiben. Der Rest Funktioniert schon so.
    Ich hab auch schon versucht Zeile 18 so zu schreiben:
    Ship* pShip = new Ship[16];
    Doch dann gibt er mir folgenden Fehler aus:
    Ship[int] for Array substrict:
    Mit dieser bezeichnung weiß ich überhaupt nichts anzufangen!
    Also könnt ihr mir Helfen ohne dass ich den gesamten Text verändern muss?

    Du solltest dann aber auch mit

    x = pShip[i]
    

    auf das Objekt zugreifen.

    Nur mal so ne' frage. Warum tippst du erst so viel code und compiliertst dann. Compilier einfach mal zwischendurch, sonst blickst du hinterher nicht mehr durch.



  • Um auf den Text von Ringding zu kommen.
    Ob mit oder ohne EDIT er zeigt mir beide male den gleichen Fehler an.
    no match for '*Ship &'
    Das Gilt für all die Zeilen in denen ich mit

    (*pShip[Poj+(Poi*4)]). ... //... steht für den Zugriff von SetShip / GetShip
    

    arbeite.
    Bei diesen Fehler weiß ich noch nicht, wie ich ihn beheben soll.

    Das Array ohne mit ihm etwas zu machen kann ich auch Kompilieren. Also kann es nicht am Kompiler liegen.
    Was meint ihr eigentlich mit der Zeile

    x = pShip[i];
    

    pShip ist doch schon ein Zeiger der auf das Objekt 'Ship' zeigt.



  • Ich meine damit eine veralgemeinerung:

    Nicht

    x = *pShip[i];
    

    sondern

    x = pShip[i];
    

    halt. Also nimm, zum beispiel:

    pShip[Poj+(Poi*4)].GetShip()
    

    wenn du es so erzeugst, wie ich es oben beschrieben habe.



  • Da hast du aber jetzt einen -> vergessen.



  • Habe ich nicht.

    Nur damit keine Missverständnise aufkommen; das hier compiliert.

    class Ship
    {
      public:
         Ship();
         ~Ship();
    	 char GetShip () const {return itsShip;}
         void SetShip (char ship) {itsShip = ship;}
    
      private:
         char itsShip;
    
    };
    
    Ship::Ship() {}
    
    int main( int argc, char *argv[] )
    {
    	Ship* pShip = new Ship[16];
    
    	int Poj = 1;
    	int Poi = 1;
    
    	char cShip = pShip[Poj+(Poi*4)].GetShip();
    
    	return 1;
    };
    

    Aber nicht mit einem ->



  • Meinst du damit, dass ich für alle Zugriffe ((*pShip[(Poi+(Poj*4))].SetShip)
    erst ein weiteres char Element Deklarieren muss.
    Wenn ja, wie soll ich dann zum schluss darauf zugreifen?
    Denn derjenige, der das benutzt soll entscheiden wo das 'S' ausgegeben werden soll und dass weiß ich noch nicht von vornherrein.
    Alles in einem weiß ich nicht wozu ich eine weitere Variable dazu Deklarieren soll und wie ich darauf zugreifen soll.



  • Nein du musst lediglich das * vor dem pShip weglassen.

    pShip[(Poi+(Poj*4))].SetShip( )
    

Log in to reply