c++ e overload di operatori

Aperto da Superbox, 28 Febbraio 2003, 22:52:22

Discussione precedente - Discussione successiva

0 Utenti e 1 Visitatore stanno visualizzando questa discussione.

Superbox

Salve a tutti, e in bocca al lupo ai mod per questo nuovo interessante forum! :)

Mi sono letto, per ora, i primi 12 giorni del manuale c++ in 21 days, ma chiaramente con la testa sono già avanti e cerco di fare cose che su tale manuale non sono scritte (nemmeno nei capitoli successivi). Dato che imparo meglio (e più in fretta), "giocando" un po' con il codice per i fatti miei... eccomi qui con un bel quesito! ;)

Sparo subito la domanda che mi assilla da mesi: come si fa un overload dell'index operator in c++?

Mi sono inchiodato in quel punto e, dopo qualche giorno di tentativi, sono riuscito a compilare lo stesso. Chiaramente i risultati non sono stati quelli sperati (il prog non fa quello che dovrebbe)... e quindi ho lasciato il mio dsw a sedimentare per settimane...:(

Ora che c'è il forum, spero possiate guidarmi verso la luce! :)

Veniamo al dunque: ecco il passo incriminato (sperando che la mancanza di tabulazioni non lo incasini troppo):

         NODO operator[] (int & posizione) const
            {
            int i;
            NODO *temp;
            temp = itsNext;
            for (i=(posizione-1); i>0; i--)
               {
               temp=temp->GetNext();
               cout<< "Mi sto spostando di 1 nodo..."<               }
            return temp->itsCol;
            }

NODO è chiaramente una classe. In pratica si tratta del mio primo tentativo di creare una lista; l'intento del mio overload è quello di poter passare da un nodo all'altro della lista "alla maniera degli array".

Esempio: pHead[2].GetCol()->GetPar(2)
dove pHead è il primo nodo, e il [2] è il parametro che gli comunica di quanti nodi si deve spostare per trovare quello che mi interessa. Il problema sta nel fatto che questo "accesso" ai nodi non me lo lascia fare.

Che io debba fare un overload anche dell'operatore -> ?

In filosofia, in religione, in etica e in politica, due e due avrebbero potuto fare cinque. Ma fino a che ci si manteneva nell'ambito di disegnare un aeroplano o un fucile, dovevano fare quattro.
- G. Orwell

overmind

a quest'ora se penso a queste cose mi viene solo in NULL nel cervello.. :D
Vedrò se posso aiutarti, per quanto riguarda l'indentazione chiedo a glide se si possono inserire i
 così possiamo indentare :cool:

Powered by Voodoo5 5500

Superbox

Ok. Grazie, Overmind. ;)

Faccio solo una precisazione, perchè rileggendo il mio post precedente non mi è sembrato abbastanza chiaro sul mio problema.

L'estratto di codice che ho riportato è sintatticamente valido (il compilatore non dà errori di sorta), quindi l'overload dell'index operator in teoria sono riuscito a farlo. Quel che invece non riesco a fare è utilizzare tale overload in pratica. Insomma, il problema è più nell'esempio che ho fatto che non nella parte di codice riportata. :h

Nell'esempio:
- pHead è il primo nodo della lista (l'unico che mi interessa conoscere, dato che per accedere a quelli successivi voglio usare appunto l'index operator, a cui comunico l'offset X, ottenenendo così uno spostamento al nodo successivo per X volte);
- GetCol è un public accessor della classe NODO e in pratica restituisce l'oggetto "contenuto" nel nodo in questione (oggetto che è un membro della classe COLONNA, che non sto a spiegarvi cos'è per non incasinare di più il discorso);
- GetPar è un public accessor della classe COLONNA.

Il problema è che il metodo da me utilizzato (pHead[2].GetCol()->GetPar(2)) è sintatticamente scorretto, quindi non riesco a compilare. Ho provato altre soluzioni sintattiche, che ora non mi vengono in mente, ma non ho cavato un ragno dal buco. :(

La domanda vera quindi è: secondo voi come faccio ad accedere agli oggetti della mia lista servendomi dell'index operator?
Ho sbagliato l'overload o sto sbagliando il metodo di accesso?

In filosofia, in religione, in etica e in politica, due e due avrebbero potuto fare cinque. Ma fino a che ci si manteneva nell'ambito di disegnare un aeroplano o un fucile, dovevano fare quattro.
- G. Orwell

Lexiw

Ma GetCol() restituisce un puntatore??


Superbox

CitazioneMa GetCol() restituisce un puntatore??

Si.

La sua declaration/implementation è:

COLONNA * GetCol() const {return itsCol};

In filosofia, in religione, in etica e in politica, due e due avrebbero potuto fare cinque. Ma fino a che ci si manteneva nell'ambito di disegnare un aeroplano o un fucile, dovevano fare quattro.
- G. Orwell

overmind

non è che puoi postare qualche fetta di codice in più?

Powered by Voodoo5 5500

Superbox

Citazionenon è che puoi postare qualche fetta di codice in più?

Potrei postarlo tutto (saranno un centinaio di righe, commentate una ad una).
Ma c'è il discorso delle tabulazioni, che andando perse renderebbero il codice molto più difficile da leggere... :(

In filosofia, in religione, in etica e in politica, due e due avrebbero potuto fare cinque. Ma fino a che ci si manteneva nell'ambito di disegnare un aeroplano o un fucile, dovevano fare quattro.
- G. Orwell

overmind

Citazione.. il discorso delle tabulazioni, che andando perse renderebbero il codice molto pi� difficile da leggere... :(

prova col pulsante # nel formato testo!

Powered by Voodoo5 5500

Superbox

Citazioneprova col pulsante # nel formato testo!

Ehm... non credo di aver capito... :o

In filosofia, in religione, in etica e in politica, due e due avrebbero potuto fare cinque. Ma fino a che ci si manteneva nell'ambito di disegnare un aeroplano o un fucile, dovevano fare quattro.
- G. Orwell

Superbox

Forse ho capito.
Ci provo. Vediamo come viene... :)


   class COLONNA
      {
      public:
         COLONNA()       
            {
            usint i = 0;
            for (i=0; i<13; i++)
               {
               char defris[] = "1";
               par = defris[0];
               }
            cout<< "colonna costruita"<            }
         ~COLONNA() { cout<< "colonna distrutta"<         char GetPar(usint n) const { return par[n]; }
         void SetPar(usint n, char ris[2])
            {
            par[n] = ris[0];
            }

      private:
         char par[13];
      };



   class NODO
      {
      public:
         NODO(COLONNA*pCol)         // COSTRUTTORE DI NODO
            {                  // la colonna viene passata come parametro
            itsCol = pCol;         // ad una colonna temporanea di nome itsCol (privata)
            itsNext = 0;         // e si assegna 0 di default al puntatore al prox nodo
            itsLast = 0;
            cout<<"E' stata creata una colonna all'indirizzo: "<            cout<< "nodo costruito"<            }
         ~NODO()                  // DISTRUTTORE DI NODO
            {                  // libera lo spazio occupato nel Free Store
            cout<<"Il nodo successivo a questo era in posizione: "<< itsNext<            cout<<"La colonna questo nodo era in posizione:      "<< itsCol<            delete itsCol;
            itsCol = 0;
            delete itsNext;
            itsNext = 0;
            itsLast = 0;
            cout<< "ma ora è un nodo distrutto"<            }
         void Insert(NODO * nodoNew)         // INSERTER DI NUOVI NODI
            {
            if (!itsNext)               // Se l'itsNext di questo nodo è 0, significa che
               {                     // questo è già l'ultimo nodo della lista, quindi
               itsNext = nodoNew;         // il nuovo nodo viene inserito subito dopo
               itsLast = nodoNew;         // Dopo la creazione del primo nodo dopo l'head,
                                    // questo IF viene ovviamente skippato
               cout<< "Questo e' il primo nodo dopo l'head"<               cout<< "Il suo indirizzo e': "<               }                     

            else                     // altrimenti si sposta all'ultimo nodo in lista
               {                     // e inserisce il nuovo nodo dopo di esso
               cout<< "Inserisco il nuovo nodo a fondo lista" << endl;
               cout<< "Il suo indirizzo e': "<               itsLast->SetNext(nodoNew);
               itsLast = nodoNew;

      // Nel primo nodo, itsLast punta SEMPRE all'ultimo nodo della lista, e serve solo per
      // inserire l'indirizzo di nodoNew nell'itsNext dell'ultimo nodo in lista.

      // In tutti i nodi "di mezzo" alla lista, invece, itsLast non serve a niente, dato che
      // il suo contenuto equivale sempre a quello di itsNext, e per questo è necessario che
      // la chiamata Insert sia effettuata SEMPRE E SOLO sul primo nodo (pHead)!!!!!

      // In caso contrario, i nuovi nodi creati verrebbero inseriti AGLI STESSI INDIRIZZI
      // dei nodi già creati in posizioni successive a quello su cui l'Insert è chiamato!

               }
            }
         void SetNext(NODO * nodo) { itsNext = nodo; }   // imposta l'indirizzo del prox nodo
         NODO * GetNext() const { return itsNext; }      // fornisce l'indirizzo del prox nodo
         COLONNA * GetCol() const { return itsCol; }   // fornisce la colonna contenuta nel nodo
         NODO operator[] (int & posizione) const
            {
            int i;
            NODO *temp;
            temp = itsNext;
            for (i=(posizione-1); i>0; i--)
               {
               temp=temp->GetNext();
               cout<< "Mi sto spostando di 1 nodo..."<               }
            return temp->itsCol;
            }

      private:
         COLONNA *itsCol;      // contenitore della colonna passata al nodo
         NODO *itsNext;         // contenitore dell'indirizzo del prox nodo in lista
         NODO *itsLast;         // contenitore dell'indirizzo dell'ultimo nodo in lista
      };


// DIMOSTRAZIONE DEL CORRETTO FUNZIONAMENTO DELLA LISTA

   NODO *pNodo = 0;            // crea un nodo temporaneo (*Nodo) e lo inizializza
   COLONNA *pCol = new COLONNA;   // crea una colonna temporanea (*pCol) nel Free Store
   int risp;
   NODO *pHead = new NODO(pCol);   // crea il nodo *pHead in Fstore e gli passa la *pCol;
   while (1)                  // inizio forever loop
      {
      cout << "Creare un'altra colonna ( numero qualunque = si, 0 = no)? ";
      cin >> risp;
      if (!risp) break;         // se risp è 0, il forever loop termina
      pCol = new COLONNA;         // crea una nuova colonna in Fstore e la passa per rif a pCol
      pNodo = new NODO(pCol);      // crea un nodo per contenere pCol e lo passa per rif a pNodo
      pHead->Insert(pNodo);      // inserisce il nuovo nodo a fondo lista
      
      }

   cout<< "Partita 1 Colonna 1: " << (pHead->GetCol())->GetPar(0) << endl;
   cout<< "Partita 3 Colonna 1: " << (pHead->GetCol())->GetPar(2) << endl;
   cout<< "Assegno 2 alla terza partita..."<< endl;
   (pHead->GetCol())->SetPar(2, "2" ;);
   //pHead[2].GetCol()->SetPar(2, "2" ;);
   //cout<< "Partita 3 Colonna 1: " << pHead[2].GetCol()->GetPar(2) << endl;
   cout<< "Partita 3 Colonna 1: " << pHead->GetCol()->GetPar(2) << endl;


// PROBLEMA: L'OPERATORE [] NON SI SA COME E SE FUNZIONA!!!

   delete pHead;
   cout << "Funziona?"<
// DIMOSTRAZIONE DEL CORRETTO FUNZIONAMENTO DELLA CLASSE COLONNA

/*   COLONNA integrale[2];

   cout <   cout << "Tredicesima partita colonna 1: " << integrale[0].GetPar(12) << endl;
   cout << "Terza partita colonna 1: " << integrale[0].GetPar(2) << endl;
   cout << "Assegno 2 alla terza partita..."<< endl;
   integrale[0].SetPar(2, "2" ;);
   cout << "Terza partita colonna 1: " << integrale[0].GetPar(2) << endl;

   cout <   cout << "Tredicesima partita colonna 2: " << integrale[1].GetPar(12) << endl;
   cout << "Terza partita colonna 2: " << integrale[1].GetPar(2) << endl;
   cout << "Assegno X alla terza partita: "<< endl;
   integrale[1].SetPar(2, "X" ;);
   cout << "Terza partita colonna 2: " << integrale[1].GetPar(2) << endl;

   cout <   cout << "Tredicesima partita colonna 1: " << integrale[0].GetPar(12) << endl;
   cout << "Terza partita colonna 1: " << integrale[0].GetPar(2) << endl;

*/

//FINE DIMOSTRAZIONE

}
 


In filosofia, in religione, in etica e in politica, due e due avrebbero potuto fare cinque. Ma fino a che ci si manteneva nell'ambito di disegnare un aeroplano o un fucile, dovevano fare quattro.
- G. Orwell