Newsgroup: it.comp.lang.c++
Titolo: Come si crea una matrice ?

Utilizzo il Visual C++ 5.0 della Microsoft. Come posso realizzare una
classe che mi implementi una matrice di puntatori ad oggetti CObject ?
Il riesco a scrivere il pezzo di codice che si occupa della allocazione
di memoria relativa alla matrice. Vi sarei molto grato se qualcuno
potesse mandarmi il codice per il costruttore ed il distruttore per
questa ipotetica classe Matrice.
Vi ringrazio anticipatamente, un saluto.
--
Stefano Gigli


Ciao Stefano, posso provare a suggerirti 2 possibili soluzioni, stà
a te poi giudicare se almeno una può adattarsi ai tuoi bisogni.
Presumo tu abbia bisogno di una matrice con grandezza variabile.
Se così non fosse allora definisci semplicemente:
    #define MYARRAY_SIZE  ......     // numero a tua discrezione
    CObject *m_ObjectArray[ MYARRAY_SIZE ];
    assegna poi ad ogni elemento con indice compreso tra 0 e
    MYARRAY_SIZE - 1, il puntatore ad un CObject.
Se no ....:
1) Prova semplicemente a implementare una classe derivata da
    CObList, troverai nell'Help-in-line un nutrito set di funzioni per
    gestire la tua lista di CObject (o derivati).
2) Se invece vuoi creare una matrice classica, avrai comunque
    bisogno almeno di 2 parametri:
    - Un puntatore al primo puntatore a CObject (o derivato).
          CObject **m_ObjectArray;
    - Una variabile che contiene il numero di puntatori a CObject
      correntemente contenuta nella tua matrice.
          int m_numObjects;
    Nel costruttore puoi inizializzare così:
MyArray::MyArray()
{
      // matrice vuota, puntatore al primo puntatore = NULL
      m_ObjectArray = NULL;
      // matrice vuota, numero di puntatori = 0
      m_numObjects = 0;
}
    Ogni volta che aggiungi un puntatore alla tua matrice:
BOOL MyArray::AddObject(CObject *newObj)
{
    if ( m_ObjectArray == NULL )
      {
        m_ObjectArray = (CObject **) malloc( sizeof(CObject *) );
        m_numObjects = 1;
      }
    else
      {
        m_numObjects ++ ;
        m_ObjectArray = (CObject **) realloc( m_ObjectArray ,
                                   sizeof(CObject *) * m_numObjects );
      }
    if (m_ObjectArray == NULL)
      {
        m_numObjects = 0;
        return(FALSE);
      }
    m_ObjectArray[m_numObjects - 1] = newObj;
    return(TRUE);
}
    Per accedere ad un puntatore, potrai farlo tramite l'indice
    all'elemento desiderato:
      obj = m_ObjectArray[indice];    // lettura
      m_ObjectArray[indice] = obj;    // scrittura
    Il parametro indice dovrà essere compreso tra 0 e m_numObjects - 1.
    Nel distruttore invece:
MyArray::~MyArray()
{
    if ( m_ObjectArray == NULL ) return;
    for ( int n = 0 ; n < m_numObjects ; n++ )
      {
        // Distruggi, se é il caso, l'oggetto per esempio con
        delete m_ObjectArray[ n ];
      }
    free( m_ObjectArray );
}
    Come vedi, avrai anche bisogno di altre funzioni per la gestione
    della tua matrice (cancellazione di un puntatore, inserimento di un
    puntatore all'interno della lista che non sia alla fine, etc.).
    Tutto questo in pratica fà sì che tu implementi qualcosa di simile
    alla classe CObList della prima soluzione, quindi .......
    Se comunque vuoi utilizzare questa soluzione, tieni presente che:
    - Per aggiungere un puntatore:
        Alloca un elemento in più con realloc e poi inserisci il nuovo
        CObject all'indice desiderato dopo aver preventivamente "shiftato"
        verso l'alto i CObject a partire dall'indice in questione.
        Per esempio, nel caso in cui tu abbia una matrice con 4 puntatori
        e ne vuoi inserire uno all'indice 2, realloca la matrice in modo che
        possa contenere 5 puntatori, ti ritrovarai così con una matrice con
        i primi 4 puntatori inalterati e il quinto non inizializzato.
        Ora esegui lo shift:
          copia l'elemento 4 nell'elemento 5   // indice 3 => indice 4
          copia l'elemento 3 nell'elemento 4   // indice 2 => indice 3
          copia il nuovo puntatore nell'elemento 3   // indice 2
        Nota: L'elemento 1 ha indice 0, l'elemento 2 ha indice 1 e così via.
        Aggiorna m_numObjects.
    - Per cancellare un puntatore:
        Esegui lo shift in senso inverso in modo che l'elemento seguente
        a quello da togliere sia copiato su quello da togliere e così via
        fino all'ultimo "shiftandoli" tutti indietro di una posizione.
        Se é il caso, distruggi preventivamente l'oggetto che stai
        togliendo.
        Tramite realloc, diminuisci di un elemento la tua matrice.
        Aggiorna m_numObjects.
Saluti Neil

 0; pNj = pNj->pPrev)
   pNj->data = pNj->pPrev->data;
  // Insert data pointer into it's proper position
  pNj->data = pOtemp;
 }
}
// Code
void CSortableObList::Sort(POSITION posStart, int iElements, int
(*CompareFunc)(CObject* pFirstObj, CObject* pSecondObj))
{ // This variation allows you to sort only a portion of the list
 // iElements can be larger than the number of remaining elements without
harm
 // iElements can be -1 which will always sort to the end of the list
 ASSERT_VALID(this);
 ASSERT( AfxIsValidAddress((CObList::CNode*)posStart,
sizeof(CObList::CNode)) );
 // Make certain posStart is a position value obtained by a GetHeadPosition
or Find member function call
 //  as there is no way to test whether or not posStart is a valid CNode
pointer from this list.
 // Ok, there is one way, we could walk the entire list and verify that
posStart is in the chain, but even
 //  for debug builds that's a bit much.
 // If the list contains no items, the HEAD position will be NULL
 if (m_pNodeHead == NULL)
  return; CObject *pOtemp;
 CObList::CNode *pNi,*pNj;
 // Walk the list
 for (pNi = (CObList::CNode*)posStart; pNi != NULL && iElements != 0; pNi =
pNi->pNext, iElements--)
 {  // Save data pointer
  pOtemp = pNi->data;
  // Walk the list backwards from pNi to the beginning of the sort or until
  // the CompareFunc() determines that this item is in it's correct position
  // shifting all items upwards as it goes
  for (pNj = pNi; pNj->pPrev != NULL && pNj->pPrev !=
((CObList::CNode*)posStart)->pPrev && CompareFunc(pNj->pPrev->data,pOtemp) >
0; pNj = pNj->pPrev)
   pNj->data = pNj->pPrev->data;
  // Insert data pointer into it's proper position
  pNj->data = pOtemp;
 }
}