Matrice c++

di il
5 risposte

Matrice c++

Salve, ho realizzato la classe matrice e ho implementato vari metodi.
Quello che non capisco è:
1. mi sono accorto facedo il debug che quando in TestMatrice.cpp chiamo m.prodotto(p), viene prima
eseguito il costruttore di copia, perchè avviene questo?
2. il costruttore di copia dovrebbe copiare il contenuto di p in m, ma questo non avviene,in quanto il prodotto viene generato
correttamente, perchè?
3. ho implementato i metodi prodotto e trasposta in modo tale che non restituiscano nulla, ovvero nel caso del prodotto viene creato un
array bidimensionale momentaneo dove viene inserito il prodotto tra l'array bidimensione contenuto in m con quello in p.
Poi, questo array contenente il prodotto viene copiato in m.
Va bene questa implementazione, oppure sarabbe stato meglio che ad esempio il prodotto restituisse una matrice?
Grazie.

matrice.cpp
#include "matrice.cpp"
#include <iostream>

matrice::matrice(int r, int c) {
	colonne = c;
	righe = r;

	elementi = new tipoelem*[righe]();
	for (int i=0; i<r; ++i)
		elementi[i] = new tipoelem[colonne]();
}

tipoelem matrice::leggiMatrice(int r, int c){
	return elementi[r][c];
}

void matrice::scriviMatrice(int r, int c, tipoelem e) {
	elementi[r][c] = e;
}

matrice::~matrice() {
	int i;

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

void matrice::trasposta() {
	int i,j;
	//array in cui viene fatta una copia del campo elementi
	tipoelem **elementiT = new tipoelem*[righe];
	for(i=0; i<righe; ++i) {
		elementiT[i] = new tipoelem[colonne];

	}

	for (i=0; i<righe; ++i){
		for (j=0; j<colonne; ++j){
			elementiT[i][j] = elementi[i][j];
		}
	}

	int righeT = colonne;
	int colonneT = righe;
	this->~matrice();
	righe = righeT;
	colonne = colonneT;

	elementi = new tipoelem*[righe]();
	for (int i=0; i<righe; ++i)
		elementi[i] = new tipoelem[colonne]();

	for (i=0; i<righe; ++i){
		for (j=0; j<colonne; ++j){
			elementi[i][j] = elementiT[j][i];
		}
	}
}

int prodottoRighe(tipoelem** elementiA, tipoelem** elementiB, int c, int i, int j) {
	tipoelem p = 0;

	for(j=0; j<c; ++j) {
		p = p + (elementiA[i][j] * elementiB[j][i]);
	}

	return p;
}

void matrice::prodotto(matrice m) {
	int i,j;

	if (colonne != m.righe)
		return;

	//array in cui viene fatta una copia di elementi
	tipoelem **elementiP = new tipoelem*[m.righe];
	for(i=0; i<m.righe; ++i) {
		elementiP[i] = new tipoelem[colonne];
	}

	for(i=0; i<righe; ++i) {
		for (j=0; j<m.colonne; ++j) {
			elementiP[i][j] = prodottoRighe(elementi, m.elementi, colonne, i, j);
		}
	}

	int r = righe;
	this->~matrice();
	colonne = m.colonne;
	righe = r;

	elementi = new tipoelem*[righe]();
	for (i=0; i<righe; ++i) {
		elementi[i] = new tipoelem[colonne]();
	}

	for(i=0; i<righe; ++i) {
		for (j=0; j<colonne; ++j) {
			elementi[i][j] = elementiP[i][j];
		}
	}

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

matrice::matrice(const matrice& m) {
	int i,j;
	colonne = m.colonne;
	righe = m.righe;

	elementi = new tipoelem*[m.righe];
	for (i=0; i<m.righe; ++i)
		elementi[i] = new tipoelem[m.colonne];

	for (i=0; i<righe; ++i){
		for (j=0; j<colonne; ++j){
			elementi[i][j] = m.elementi[i][j];
		}
	}
}

matrice& matrice::operator=(const matrice& m) {

	int i,j;

	if (this == &m)
		return *this;

	if ((m.colonne != colonne) || (m.righe != righe)) {
		this->~matrice();
		this->elementi = new tipoelem*[m.righe];
		for (i=0; i<m.righe; ++i)
			this->elementi[i] = new tipoelem[m.colonne];

		colonne = m.colonne;
		righe = m.righe;

		for (i=0; i<righe; ++i){
			for (j=0; j<colonne; ++j){
				elementi[i][j] = m.elementi[i][j];
			}
		}
	}


	return *this;
}

void matrice::toString() {
	int i,j;

	for(i=0;i<righe;++i) {
		for(j=0;j<colonne;++j) {
			std::cout << elementi[i][j] << " ";
		}
		std::cout << std::endl;
	}
}
matrice.h

#ifndef MATRICE_H_
#define MATRICE_H_
typedef double tipoelem;

class matrice {
	public:
		matrice(int, int);
		tipoelem leggiMatrice (int, int);
		void scriviMatrice(int, int, tipoelem);
		~matrice();
		void trasposta();
		void prodotto(matrice);
		matrice(const matrice&);
		matrice& operator=(const matrice&);
		void toString();
	private:
		int righe;
		int colonne;
		tipoelem **elementi;
};


#endif /* MATRICE_H_ */
TestMatrice.cpp

#include <iostream>
#include "matrice.h"

int main(void){

	matrice m(2,3);
	m.scriviMatrice(0,0,1);
	m.scriviMatrice(0,1,2);
	m.scriviMatrice(0,2,3);
	m.scriviMatrice(1,0,4);
	m.scriviMatrice(1,1,5);
	m.scriviMatrice(1,2,6);
	std::cout << "matrice m" << std::endl;
	m.toString();

	matrice p(3,3);
	p.scriviMatrice(0,0,1);
	p.scriviMatrice(0,1,1);
	p.scriviMatrice(0,2,1);
	p.scriviMatrice(1,0,1);
	p.scriviMatrice(1,1,1);
	p.scriviMatrice(1,2,1);
	p.scriviMatrice(2,0,1);
	p.scriviMatrice(2,1,1);
	p.scriviMatrice(2,2,1);

	std::cout << "matrice p" << std::endl;
	p.toString();

	m.prodotto(p);
	std::cout << "matrice prodotto m x p" << std::endl;
	m.toString();

	m.trasposta();
	std::cout << "matrice trasposta" << std::endl;
	m.toString();

	std::cout << "copia della matrice utilizzando il costruttore di copia" << std::endl;
	matrice t(m);
	t.toString();

	matrice cp(0,0);
	std::cout << "copia della matrice attraverso il simbolo =" << std::endl;
	cp = t;
	cp.toString();

	system("PAUSE");

	return 0;
}

5 Risposte

  • Re: Matrice c++

    1) Perché gli passi l'operando per copia. Passaglielo come const reference e non si attiva il costruttore di copia.
    2) Non ho capito.
    3) È una tua scelta. Secondo me era meglio restituire il risultato e lasciare l'originale intatta, come avviene nei linguaggi tipo matlab.
  • Re: Matrice c++

    Io ho definito il costruttore di copia "matrice(const matrice&);" all'interno della classe matrice.
    quello che non mi spiego è il perchè quando chiamo m.prodotto(p) viene chiamato il costruttore di copia.
    Il costruttore di copia non dovrebbe essere chiamato solo quando scrivo "matrice t(m)" ?
  • Re: Matrice c++

    Mi riferivo alla funzione prodotto. Siccome gli passi l'argomento per copia, deve costruire una copia dell'argomento. Se non vuoi attivare il costruttore di copia, devi dichiararla così:
    void prodotto(const matrice&)
  • Re: Matrice c++

    Ma quindi, quando io scrivo m.prodotto(p), viene chiamato il costruttore di copia,che copia i campi privati di p nei campi privati di m?
  • Re: Matrice c++

    Sì. Per m intendo il parametro che tu hai chiamato m nella definizione di prodotto, non m la matrice iniziale da cui hai chiamato la funzione.
Devi accedere o registrarti per scrivere nel forum
5 risposte