Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - Classe per matrici - metodo operator+ malfunzionante.
Forum - C/C++ - Classe per matrici - metodo operator+ malfunzionante.

Avatar
F@810 (Normal User)
Newbie


Messaggi: 4
Iscritto: 18/09/2007

Segnala al moderatore
Postato alle 20:57
Mercoledì, 24/11/2010
Questo topic è stato chiuso dal moderatore

Salve a tutti!
Io sto scrivendo un programma per lavorare con le matrici usando le classi. Per le operazioni uso gli operatori. Di seguito posto parte del codice, dove mostro come ho implementato gli operatori += e +. In main ho creato due semplici matrici 3 * 3 e ho provato a sommarle.

Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <iomanip>
  3. using namespace std;
  4.  
  5. class Matrix
  6. {
  7.     private:
  8.         string name; // matrix's name
  9.         int m, n; // dimensions (m - rows, n - cols)
  10.         double *data; // data, stored row by row
  11.     public:
  12.                 Matrix(string, int, int, double[]); // constructor
  13.         void operator+=(Matrix); // add a matrix to this
  14.         Matrix operator+(Matrix); // add two matrix
  15.         friend ostream& operator<<(ostream &out, Matrix A); // stream out
  16. };
  17.  
  18. Matrix::Matrix(string name, int n, int m, double *data)
  19. {
  20.     this->name = name, this->n = n, this->m = m, this->data = data; // assignements
  21. }
  22.  
  23. void Matrix::operator+=(Matrix rhs)
  24. {
  25.     if (this->m != rhs.m || this->n != rhs.n) {/* exception - not yet implemented */}
  26.     for (int i = 0; i < this->m * this->n; i++) this->data[i] += rhs.data[i]; // add to each element of this the equivalent element of rhs
  27. }
  28.  
  29. Matrix Matrix::operator+(Matrix rhs)
  30. {
  31.     if (this->m != rhs.m || this->n != rhs.n) {/* exception - not yet implemented */}
  32.     double data_out[this->m * this->n]; // temporany array with new data
  33.     for (int i = 0; i < this->m * this->n; i++) data_out[i] = this->data[i]; // copy the data
  34.     Matrix out = Matrix(this->name + " + " + rhs.name, this->m, this->n, data_out); // create a copy of this
  35.     out += rhs; // add tho the copy of this rhs
  36.     return out; // return the copy
  37. }
  38.  
  39. ostream& operator<<(ostream &out, Matrix A)
  40. {
  41.     out << A.name << " =";
  42.     for (int i = 0; i < A.m * A.n; i++)
  43.     {
  44.         out << setw(10);
  45.         if (i % A.n) out << setw(10);
  46.         else out << endl << endl;
  47.         out << A.data[i];
  48.     }
  49.     out << endl;
  50.     return out;
  51. }
  52.  
  53. int main()
  54. {
  55.     // creo le matrici
  56.     double a[9] = {1, 2, 3, 4, 5, 6, 7, 8 ,9};
  57.     Matrix A = Matrix("A", 3, 3, a);
  58.     double b[] = {10, 11, 12, 13, 14, 15, 16, 17, 18};
  59.     Matrix B = Matrix("B", 3, 3, b);
  60.    
  61.     // test
  62.     cout << A << endl << B << endl;
  63.     cout << A + B << endl; // ??????????????????????????
  64.     system("pause");
  65.     return 0;
  66. }



In breve, la classe contiene una stringa per il nome della matrice, le dimensioni di essa e tutti gli elementi salvati in un array di tipo double riga per riga (ho commentato il codice in inglese spero sia comprensibile).
L'operatore += funziona correttamente. Il problema è che l'operazione A + B invece non funziona correttamente, eseguendo il codice viene visualizzata una matrice con valori casuali.
La strategia che ho utilizzato è la seguente:
1. Copia i dati di this in un array temporaneo.
2. Crea una nuova matrice col costruttore a partire dall'array temporaneo.
3. Applica l'operatore += alla nuova matrice con rhs come argmoento
4. Restituisci la matrice.
Premetto che ho già provato una moltitudine di soluzioni alternative senza successo (aggiungendo tutte le combinazioni possibili di "const" e "&" agli argomenti e alle funzioni), e che ho lo stesso problema su tutte le altre funzioni che ho implementato (ad es Matrix * Matrix).
Inoltre anche impementando in maniera diversa l'operatore + (senza usare il += già implementato, per intenderci) ho lo stesso problema.
Sapete dirmi cosa sbaglio? C'entra per caso con il fatto che l'attributo double *data non ha (non può avere) dimensione fissa?

Grazie in anticipo,
Fabio

PS:
1. uso Dev-C++ (che io trovo buono nonostante tutte le critiche che ho letto)
2. #include <iomanip> serve per la funzione setw() in ostream& operator<<(ostream&, Matrix). Se non riuscite a compilare togliete #include <iomanip> e sostituite setw(10) con "\t".
3. system("pause"); --> windows...

PM
Avatar
F@810 (Normal User)
Newbie


Messaggi: 4
Iscritto: 18/09/2007

Segnala al moderatore
Postato alle 23:20
Mercoledì, 24/11/2010
Ok problema risolto :)
Chiaramente dopo un giorno di tentativi vani l'intuizione è arrivata solo dopo aver postato il codice sul forum :yup: un ultimo tentativo per scoprire che si era a un passo dalla soluzione!
Bastava inizializzare data_out in Matrix Matrix::operator+(Matrix rhs) come pointer:
Codice sorgente - presumibilmente C#

  1. Matrix Matrix::operator+(Matrix rhs)
  2. {
  3.     if (this->m != rhs.m || this->n != rhs.n) {/* exception - not yet implemented */}
  4.     double *data_out = new double[this->m * this->n]; // temporany array with new data
  5.     for (int i = 0; i < this->m * this->n; i++) data_out[i] = this->data[i]; // copy the data
  6.     Matrix out = Matrix(this->name + " + " + rhs.name, this->m, this->n, data_out); // create a copy of this
  7.     out += rhs; // add tho the copy of this rhs
  8.     return out; // return the copy
  9. }


comunque posto anche una versione migliore che non fa uso dell'operatore +=
Codice sorgente - presumibilmente VB.NET

  1. Matrix Matrix::operator+(Matrix rhs)
  2. {
  3.     if (this->m != rhs.m || this->n != rhs.n) {/* exception - not yet implemented */}
  4.     double *data = new double[this->m * this->n];
  5.     for (int i = 0; i < this->m * this->n; i++) data[i] = this->data[i] + rhs.data[i]; // copy the data
  6.     return Matrix(this->name + " + " + rhs.name, this->m, this->n, data);
  7. }



PM