07/09/18 16:45
AldoBaldo
"Ispirato" dalla discussione sulle "matrici" propostaci da comtel, ho voluto provare a mettere insieme un template che si occupi (in C++, ovviamente) di quel tipo di costrutto, ovvero di "finte" matrici implementate in memoria come vettori. Siccome è la prima volta che metto le mani sui template, mi farebbe piacere sapere se ho applicato correttamente quel che avrei dovuto applicare correttamente. Intendo, il codice sembra funzionare ma... mi sfugge qualche particolare importante che dovrei conoscere e del quale dovrei tenere conto?
EDIT: siccome queste cose le conservo per poi riutilizzarle magari anche dopo un bel po' di tempo, mi son preparato un file di promemoria che ho messo in tinyurl.com/…
#ifndef TEMPLATE_MATRICE_H #define TEMPLATE_MATRICE_H #include <stdlib.h> template<class TIPO> class MATRICE { public: MATRICE(); MATRICE( size_t colonne, size_t righe ); virtual ~MATRICE(); MATRICE(const MATRICE& other); // modifica bool Dimensiona( size_t colonne, size_t righe, bool preserva_dati = true ); // lettura size_t QColonne( void ) const { return qc; } size_t QRighe( void ) const { return qr; } size_t QCelle( void ) const { return qc*qr; } MATRICE& operator=(const MATRICE& other); TIPO& operator()( size_t x, size_t y ); static const char *kStrErrNoDim; static const char *kStrErrNoCoo; protected: private: TIPO *m; // l'array che contiene la matrice size_t qr; // quantita' di righe size_t qc; // quantita' di colonne }; template<class TIPO>const char *MATRICE<TIPO>::kStrErrNoDim = "template MATRICE: dimensionamento fallito"; template<class TIPO>const char *MATRICE<TIPO>::kStrErrNoCoo = "template MATRICE: coordinate esterne alla matrice"; template<class TIPO> MATRICE<TIPO>::MATRICE() { m = NULL; qc = qr = 0; } template<class TIPO> MATRICE<TIPO>::MATRICE( size_t colonne, size_t righe ) { m = NULL; qc = qr = 0; if( !Dimensiona(colonne,righe) ) throw kStrErrNoDim; } template<class TIPO> MATRICE<TIPO>::~MATRICE() { if( m ) delete[] m; } template<class TIPO> bool MATRICE<TIPO>::Dimensiona( size_t colonne, size_t righe, bool preserva_dati ) { try { TIPO *mAux = new TIPO[colonne*righe]; if( preserva_dati ) { for( size_t max_rig=righe<qr?righe:qr, r=0; r<max_rig; ++r ) for( size_t max_col=colonne<qc?colonne:qc, c=0; c<max_col; ++c ) mAux[r*max_col+c] = m[r*qc+c]; } if( m ) delete[] m; m = mAux; qc = colonne; qr = righe; return true; } catch( ... ) { return false; } } template<class TIPO> MATRICE<TIPO>::MATRICE(const MATRICE& other) { m = NULL; qc = qr = 0; *this = other; } template<class TIPO> MATRICE<TIPO>& MATRICE<TIPO>::operator=(const MATRICE<TIPO>& rhs) { if (this == &rhs) return *this; // handle self assignment if( !Dimensiona(rhs.qc,rhs.qr,false) ) throw kStrErrNoDim; for( size_t r=0; r<qr; ++r ) for( size_t c=0; c<qc; ++c ) m[r*qc+c] = rhs.m[r*qc+c]; return *this; } template<class TIPO> TIPO& MATRICE<TIPO>::operator()( size_t x, size_t y ) { if( x>=qc||y>=qr ) throw kStrErrNoCoo; return m[y*qc+x]; } #endif // TEMPLATE_MATRICE_H
EDIT: siccome queste cose le conservo per poi riutilizzarle magari anche dopo un bel po' di tempo, mi son preparato un file di promemoria che ho messo in tinyurl.com/…
Ultima modifica effettuata da AldoBaldo 07/09/18 19:44
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.