Newsgroup: it.comp.lang.c++
Titolo: matrice di oggetti: dichiarazione, allocazione e rilascio

Ho una classe Griglia che rappresenta una matrice di punti dello spazio.
Per i punti ho la classe Point.
Come dichiaro questa matrice? io ho pensato ad un "doppio puntatore" Point
**
esso dovrebbe rappresentare un puntatore ad un puntatore di oggetti Point,
se non sbaglio,
e quindi la matrice diventa un vettore di puntatori a vettori di oggetti
Point? ....ho un po di dubbi.....
Come faccio l'allocazione della memoria (nel costruttore di Griglia) con
l'operatore new?
Come posso scrivere il distruttore?
Inserisco qui sotto quello che ho pensato io!
Grazie dell'aiuto.
class Griglia
{
     private:
           Point ** punti;
           int dim1;
           int dim2;
      public:
           Griglia( int d1, int d2 );
           ~Griglia;
           ..............
}
Griglia( int d1, int d2 )
{
         this->punti = new * Point[ this->dim1= d1 ];
         for( in i =0; i< this->dim1; i++)
                    this->punti[ i ] = new Point[ this->dim2 = d2 ];
}

 Come posso scrivere il distruttore?
Perchè non usi vector? Farà un po' schifo come dichiarazione, ma è *molto* 
più semplice per tutto il resto. Esempio:
class Griglia
{
private:
	vector <vector <Point> > punti;
public:
	Griglia (int d1, int d2);
	~Griglia ();
};
Griglia::Griglia (int d1, int d2)
	: punti (d1)
{
	for (size_t i = 0; i < d1; ++i)
		v [i].reserve (d2);
	// Adesso usi v[i][j] come fosse una matrice
}
Griglia::~Griglia ()
{
	/* Non fa niente, quindi non è obbligatorio metterlo. Comunque quando viene 
chiamato questo distruttore, viene anche chiamato il distruttore di punti, 
che si occupa automaticamente di rilasciare la memoria usata dal vector di 
vector. */
}
Ti faccio solo alcuni piccoli appunti sul tuo codice:
 > class Griglia
 > {
 >      private:
 >            Point ** punti;
 >            int dim1;
 >            int dim2;
 >       public:
 >            Griglia( int d1, int d2 );
 >            ~Griglia;
Le tonde non sono facoltative
 >            ..............
 > }
 >
 >
 > Griglia( int d1, int d2 )
Griglia::Griglia (int d1, int d2)
 > {
 >          this->punti = new * Point[ this->dim1= d1 ];
new si scrive senza asterisco, e this-> non è obbligatorio, anzi IMHO 
rende il codice meno leggibile. Ma se lo usi per farti apparire un menù 
pop-up sei scusato ;-) In sintesi meglio sostituire con:
dim1 = d1; dim2 = d2;		// Oppure usi la lista di inizializzazione
punti = new Point [dim1];
 >          for( in i =0; i< this->dim1; i++)
Meglio size_t al posto di int
 >                     this->punti[ i ] = new Point[ this->dim2 = d2 ];
 >
 > }
Comunque l'allocazione era esatta. Mancava il distruttore, che avrebbe 
dovuto essere qualcosa tipo:
Griglia::~Griglia ()
{
	for (size_t i = 0; i < d1; ++i)
		delete [] punti [i];
	delete [] punti;
}
Se non capisci bene qualcosa chiedi pure. Ciao.
-- 
Andrea Bergia - studente
Linux Registred User #281550

 punti = new Point [dim1];
Non proprio. 'punti' è un 'Point**'. La sintassi giusta per allocare un
array di puntatori (perchè è questo che l'OP voleva fare) è:
  punti = new Point* [ dim1 ];
Max


perche' e' meglio size_t?
e' una regola generale?
Ciao. Mauro.

   punti = new Point* [ dim1 ];
Cosi funziona anche come l'avevo definito io, senza il vector.
Grazie ciao.
Mauro.

 e' una regola generale?
size_t č senza segno. Ovviamente non puoi accedere all'elemento -3, quindi 
  usare un unsigned č "meglio". Inoltre, dato che vector::size() ritorna 
un size_t e vector::operator [] prende un size_t, per evitare warning del 
compilatore sul fatto che confronti numeri signed con unsigned č meglio 
usare size_t.
