Creare operatore assegnamento per la classe matrice

di il
8 risposte

Creare operatore assegnamento per la classe matrice

Salve ragazzi, sono nuovo sia nel forum ma soprattutto nuovo con la programmazione ad oggetti.
Per un esercizio devo creare una classe matrice in C++ che gestisce un array dinamico e creare distruttore, costruttore, metodi per il prodotto e trasposta.

Nel file "matrice.h" la definizione della classe è questa (omettendo gli altri metodi che per ora non mi interessano):
#include <iostream>

class matrice {
	private:
			int righe;
			int colonne;
			double **elementi;
	public:
			matrice(int r, int c); //Costruttore
			~matrice(); //Distruttore
			matrice(const matrice &altra); //Costruttore di copia
			void stampa(); //Stampa matrice
			matrice& operator=(const matrice& altra); //Overloading operatore assegnamento
};
Nel file "matrice.cpp" ho creato le seguenti funzioni:
#include <iostream>
#include "matrice.h"

//Costruttore
matrice::matrice(int r, int c){

	righe = r;
	colonne = c;
	elementi = new double*[righe];
	for (int i=0; i<righe; i++){
		elementi[i] = new double[colonne];
		for(int j=0; j<colonne; j++){ //Riempio la matrice per testare il funzionamento
			elementi[i][j] = j;
		}
	}
}

//Distruttore
matrice::~matrice(){

    for (int i=0; i<righe; i++){
        delete[] elementi[i];
    }
    delete[] elementi;
}

//Costruttore di copia
matrice::matrice(const matrice &altra)
{
    righe = altra.righe;
    colonne = altra.colonne;
    elementi = new double*[righe];
    for (int i=0; i<righe; i++){
        elementi[i] = new double[colonne];
        for(int j=0; j<colonne; j++){
        	elementi[i][j] = altra.elementi[i][j];
        }
    }
}

//Stampa matrice
void matrice::stampa(){

	using namespace std;
	int i, j;
	for(i=0; i<righe; i++){
		for(j=0; j<colonne; j++){
			cout << elementi[i][j] << "\t";
		}
		cout << endl;
	}
}

//Overloading operatore assegnamento
matrice& matrice::operator=(const matrice& altra)
{
	//Non so come fare!!!!
}


Innanzitutto vorrei capire se ho scritto correttamente il metodo distruttore, costruttore e costruttore di copia.
Inoltre non so davvero come scrivere il codice per l'operatore di assegnamento "=". Ho capito che devo de-allocare la matrice attuale e riallocarla dinamicamente con le dimensioni e gli elementi della matrice passata come parametro ma non ho capito come fare.
Qualcuno mi può aiutare?

8 Risposte

  • Re: Creare operatore assegnamento per la classe matrice

    Non vedo errori, ma per controllare fai dei test e vedi se non crashano e danno i risultati che ti aspetti.
    Sull'operatore di assegnazione cosa c'è di difficile? Basta deallocare la matrice con lo stesso for usato per il metodo distruttore e poi ricostruirla con i parametri della seconda. Prima però gli farei controllare se hanno già le stesse dimensioni, così risparmi i cicli di delete e new e passi dirattamente alla copia dei valori.
  • Re: Creare operatore assegnamento per la classe matrice

    Ciao, in generale quello fatto finora mi sembra corretto, giusto un paio di osservazioni:

    - perché includi iostream in matrice.h?
    - anche quel using namespace std all'interno di stampa() può essere evitato;
    - non so se conosci gli argomenti di default, ma potresti anche modificare il prototipo del primo costruttore in
    matrice(int r, int c, double n = 0);
    Per quanto riguarda l'overload dell'operatore di assegnazione mi accodo a quanto detto da @Alexv, anche se relativamente a

    Alexv ha scritto:


    Basta deallocare la matrice con lo stesso for usato per il metodo distruttore
    volendo si può anche richiamare esplicitamente il distruttore.
  • Re: Creare operatore assegnamento per la classe matrice

    Grazie a entrambi per le risposte. Nel frattempo penso di aver capito come scrivere l'operatore di assegnamento.
    
    matrice& matrice::operator=(const matrice& altra)
    {
        this->~matrice();
    	righe = altra.righe;
    	colonne = altra.colonne;
        elementi = new double*[righe];
        for (int i=0; i<righe; i++){
            elementi[i] = new double[colonne];
            for(int j=0; j<colonne; j++){
            	elementi[i][j] = altra.elementi[i][j];
            }
        }
    	return *this;
    }
    
    
    è giusto???
  • Re: Creare operatore assegnamento per la classe matrice

    Nippolo ha scritto:


    volendo si può anche richiamare esplicitamente il distruttore.
    Non lo so, qui lo sconsiglia
    https://isocpp.org/wiki/faq/dtors#dont-call-dtor-on-local
  • Re: Creare operatore assegnamento per la classe matrice

    s.capone7 ha scritto:


    è giusto???
    Mi sembra di sì, ma dovresti aggiungere un controllo all'inizio... cosa succederebbe se nel main() scrivi:
    matrice m(2, 3);
    m = m;
    ??

    Alexv ha scritto:


    Non lo so, qui lo sconsiglia
    Nel caso specifico credo non ci sia nessuna differenza, in quanto quello che andresti a scrivere senza voler richiamare esplicitamente il distruttore coincide esattamente con il corpo del distruttore stesso.
  • Re: Creare operatore assegnamento per la classe matrice

    Nippolo ha scritto:


    s.capone7 ha scritto:


    è giusto???
    Mi sembra di sì, ma dovresti aggiungere un controllo all'inizio... cosa succederebbe se nel main() scrivi:
    matrice m(2, 3);
    m = m;
    ??

    Alexv ha scritto:


    Non lo so, qui lo sconsiglia
    Nel caso specifico credo non ci sia nessuna differenza, in quanto quello che andresti a scrivere senza voler richiamare esplicitamente il distruttore coincide esattamente con il corpo del distruttore stesso.
    Ho migliorato il codice seguendo il tuo consiglio. Ho operato nel modo giusto? Grazie infinite comunque.
    
    matrice& matrice::operator=(const matrice& altra)
    {
    	if(this == &altra) return *this;
    	else
    	{
    		int i, j;
    		if(colonne != altra.colonne || righe != altra.righe)
    		{
    			this->~matrice();
    			righe = altra.righe;
    			colonne = altra.colonne;
    			elementi = new double*[righe];
    			for (int i=0; i<righe; i++){
    				elementi[i] = new double[colonne];
    			}
    		}
    		for(i=0; i<righe; i++)
    			for(j=0; j<colonne; j++)
    				elementi[i][j] = altra.elementi[i][j];
    	}
    	return *this;
    }
    
    
  • Re: Creare operatore assegnamento per la classe matrice

    Direi che va bene, comunque se modifichi la condizione iniziale in
    this != &altra
    puoi evitare il doppio return.
  • Re: Creare operatore assegnamento per la classe matrice

    Si potrebbe migliorare ancora. Per esempio se il numero di colonne è diverso, ma hanno lo stesso numero di righe...
Devi accedere o registrarti per scrivere nel forum
8 risposte