Procedura: creazione di una raccolta indipendente dai tipi

Questo articolo illustra come creare raccolte indipendenti dai tipi per i tipi di dati personalizzati. Gli argomenti includono:

La libreria di classi Microsoft Foundation fornisce raccolte predefinite indipendenti dai tipi basate sui modelli C++. Poiché si tratta di modelli, queste classi consentono di garantire sicurezza dei tipi e facilità d'uso senza il cast dei tipi e altre operazioni aggiuntive coinvolte nell'uso di una classe non standard per questo scopo. L'esempio MFC COLLECT illustra l'uso di classi di raccolta basate su modello in un'applicazione MFC. In generale, usare queste classi ogni volta che si scrive nuovo codice di raccolte.

Uso di classi basate su modello per il tipo Cassaforte ty

Per usare classi basate su modello

  1. Dichiarare una variabile del tipo di classe della raccolta. Ad esempio:

    CList<int, int> m_intList;
    
  2. Chiamare le funzioni membro dell'oggetto raccolta. Ad esempio:

    m_intList.AddTail(100);
    m_intList.RemoveAll();
    
  3. Se necessario, implementare le funzioni helper e SerializeElements. Per informazioni sull'implementazione di queste funzioni, vedere Implementazione di funzioni helper.

In questo esempio viene illustrata la dichiarazione di un elenco di numeri interi. Il primo parametro nel passaggio 1 è il tipo di dati archiviati come elementi dell'elenco. Il secondo parametro specifica il modo in cui i dati devono essere passati e restituiti dalle funzioni membro della classe di raccolta, ad esempio Add e GetAt.

Implementazione di funzioni helper

Le classi CArraydi raccolta basate su modello , CListe CMap usano cinque funzioni helper globali che è possibile personalizzare in base alle esigenze per la classe di raccolta derivata. Per informazioni su queste funzioni helper, vedere Collection Class Helpers (Helper di classi di raccolta) nella Guida di riferimento per MFC. L'implementazione della funzione di serializzazione è necessaria per la maggior parte degli usi delle classi di raccolta basate su modello.

Serializzazione degli elementi

Le CArrayclassi , CListe CMap chiamano SerializeElements per archiviare gli elementi della raccolta o leggerli da un archivio.

L'implementazione predefinita della SerializeElements funzione helper esegue una scrittura bit per bit dagli oggetti all'archivio o una lettura bit per bit dall'archivio agli oggetti, a seconda che gli oggetti vengano archiviati o recuperati dall'archivio. Eseguire l'override SerializeElements se questa azione non è appropriata.

Se la raccolta archivia gli oggetti derivati da CObject e si usa la IMPLEMENT_SERIAL macro nell'implementazione della classe di elementi della raccolta, è possibile sfruttare le funzionalità di serializzazione incorporate in CArchive e CObject:

CArray< CPerson, CPerson& > personArray;

template <> void AFXAPI SerializeElements <CPerson>(CArchive& ar,
   CPerson* pNewPersons, INT_PTR nCount)
{
   for (int i = 0; i < nCount; i++, pNewPersons++)
   {
      // Serialize each CPerson object
      pNewPersons->Serialize(ar);
   }
}

Operatori di inserimento di overload per CArchive la chiamata CObject::Serialize (o un override di tale funzione) per ogni CPerson oggetto.

Utilizzo di classi di raccolta nontemplate

MFC supporta anche le classi di raccolta introdotte con MFC versione 1.0. Queste classi non sono basate sui modelli. Possono essere usati per contenere i dati dei tipi CObject*supportati , , UINTDWORDe CString. È possibile usare queste raccolte predefinite, ad esempio CObList, per contenere raccolte di oggetti derivati da CObject. MFC fornisce anche altre raccolte predefinite per contenere tipi primitivi, ad UINT esempio e puntatori void (void*). In generale, tuttavia, è spesso utile definire raccolte indipendenti dai tipi per contenere oggetti di una classe più specifica e i relativi derivati. Si noti che questa operazione con le classi di raccolta non basate su modelli è più funzionante rispetto all'uso delle classi basate su modelli.

Esistono due modi per creare raccolte indipendenti dai tipi con le raccolte nonmplate:

  1. Usare le raccolte non di tipo, con cast dei tipi, se necessario. Questo è l'approccio più semplice.

  2. Derivare da ed estendere una raccolta non indipendente dai tipi.

Per usare le raccolte non di tipo con cast dei tipi

  1. Usare una delle classi nontemplate, ad esempio CWordArray, direttamente.

    Ad esempio, è possibile creare un CWordArray oggetto e aggiungervi eventuali valori a 32 bit, quindi recuperarli. Non c'è niente di più da fare. È sufficiente usare la funzionalità predefinita.

    È anche possibile usare una raccolta predefinita, ad esempio CObList, per contenere tutti gli oggetti derivati da CObject. Una CObList raccolta è definita per contenere i puntatori a CObject. Quando si recupera un oggetto dall'elenco, potrebbe essere necessario eseguire il cast del risultato al tipo corretto perché le CObList funzioni restituiscono puntatori a CObject. Ad esempio, se si archiviano CPerson oggetti in una CObList raccolta, è necessario eseguire il cast di un elemento recuperato come puntatore a un CPerson oggetto . Nell'esempio seguente viene utilizzata una CObList raccolta per contenere CPerson oggetti:

    CPerson* p1 = new CPerson();
    CObList myList;
    
    myList.AddHead(p1);   // No cast needed
    CPerson* p2 = (CPerson*)myList.GetHead();
    

    Questa tecnica di utilizzo di un tipo di raccolta predefinito e il cast in base alle esigenze della raccolta possono essere adeguate per molte delle esigenze di raccolta. Se sono necessarie altre funzionalità o più sicurezza dei tipi, usare una classe basata su modello o seguire la procedura successiva.

Per derivare ed estendere una raccolta non indipendente dai tipi

  1. Derivare la classe di raccolta personalizzata da una delle classi nonmplate predefinite.

    Quando si deriva la classe, è possibile aggiungere funzioni wrapper indipendenti dai tipi per fornire un'interfaccia indipendente dai tipi alle funzioni esistenti.

    Ad esempio, se è stato derivato un elenco da CObList per contenere CPerson oggetti, è possibile aggiungere le funzioni AddHeadPerson wrapper e GetHeadPerson, come illustrato di seguito.

    class CPersonList : public CObList
    {
    public:
       void AddHeadPerson(CPerson* person)
       {
          AddHead(person);
       }
    
       const CPerson* GetHeadPerson()
       {
          return (CPerson*)GetHead();
       }
    };
    

    Queste funzioni wrapper forniscono un modo indipendente dai tipi per aggiungere e recuperare CPerson oggetti dall'elenco derivato. È possibile notare che per la GetHeadPerson funzione è sufficiente incapsulare il cast dei tipi.

    È anche possibile aggiungere nuove funzionalità definendo nuove funzioni che estendono le funzionalità della raccolta anziché eseguire semplicemente il wrapping delle funzionalità esistenti nei wrapper indipendenti dai tipi. Ad esempio, l'articolo Eliminazione di tutti gli oggetti in un insieme CObject descrive una funzione per eliminare tutti gli oggetti contenuti in un elenco. Questa funzione può essere aggiunta alla classe derivata come funzione membro.

Vedi anche

Raccolte