Cerca nel sito:
ricerca
avanzata

Frasi Celebri...

Noi viviamo in un mondo di fantasie e illusioni. Il nostro compito pi? arduo ? trovare la realt

Iris Murdoch 

Sondaggio:

Quale sistema operativo preferite?

Linux
Windows
DOS
MacOs
UNIX

visualizza risultati


 

Classi contenitore

 

Supponiamo di voler realizzare una lista generica facilmente riutilizzabile. Sulla base di quanto visto fino ad ora l'unica soluzione possibile sarebbe quella di realizzare una lista che contenga puntatori ad una generica classe TInfo che rappresenta l'interfaccia di un generico oggetto memorizzabile nella lista:


  class TInfo {
    /* ... */
  };

  class TList {
    public:
      TList();
      ~TList();
      void Store(TInfo* Object);
      /* ... */

    private:
      class TCell {
        public:
          TCell(TInfo* Object, TCell* Next);
          ~TCell();
          TInfo* GetObject();
          TCell* GetNextCell();
        private:
          TInfo* StoredObject;
          TCell* NextCell;
      };

      TCell* FirstCell;
  };

  TList::TCell::TCell(TInfo* Object, TCell* Next)
       : StoredObject(Object), NextCell(Next) {}

  TList::TCell::~TCell() {
    delete StoredObject;
  }

  TInfo* TList::TCell::GetObject() {
    return StoredObject;
  }

  TList::TCell* TList::TCell::GetNextCell() {
    return NextCell;
  }

  TList::TList() : FirstCell(0) {}

  TList::~TList() {
    TCell* Iterator = FirstCell;
    while (Iterator) {
      TCell* Tmp = Iterator;
      Iterator = Iterator -> GetNextCell();
      delete Tmp;
    }
  }

  void TList::Store(TInfo* Object) {
    FirstCell = new TCell(Object, FirstCell);
  }


L'esempio mostra una parziale implementazione di una tale lista (che assume la proprieta` degli oggetti contenuti), nella realta` TInfo e/o TList molto probabilmente sarebbero diverse al fine di fornire un meccanismo per eseguire delle ricerche all'interno della lista e varie altre funzionalita`. Tuttavia il codice riportato e` sufficiente ai nostri scopi.
Una implementazione di questo tipo funziona, ma soffre di (almeno) un grave difetto: la lista puo` memorizzare tutta una gerarchia di oggetti, e questo e` utile e comodo in molti casi, tuttavia in molte situazioni siamo interessate a liste di oggetti omogenei e una soluzione di questo tipo non permette di verificare a compile time che gli oggetti memorizzati corrispondano tutti ad uno specifico tipo. Potremmo cercare (e trovare) delle soluzioni che ci permettano una verifica a run time, ma non a compile time. Supponete di aver bisogno di una lista per memorizzare figure geometriche e una'altra per memorizzare stringhe, nulla vi impedisce di memorizzare una stringa nella lista delle figure geometriche (poiche` le liste memorizzano puntatori alla classe base comune TInfo). Sostanzialmente una lista di questo tipo annulla i vantaggi di un type checking statico.
Alcune osservazioni...
In effetti non e` necessario che il compilatore fornisca il codice macchina relativo alla lista ancora prima che un oggetto lista sia istanziato, e` sufficiente che tale codice sia generabile nel momento in cui e` noto l'effettivo tipo degli oggetti da memorizzare. Supponiamo di avere una libreria di contenitori generici (liste, stack...), a noi non interessa il modo in cui tale codice sia disponibile, ci basta poter dire al compilatore "istanzia una lista di stringhe", il compilatore dovrebbe semplicemente prendere la definizione di lista data sopra e sostituire al tipo TInfo il tipo TString e quindi generare il codice macchina relativo ai metodi di TList. Naturalmente perche` cio` sia possibile il tipo TString dovrebbe essere conforme alle specifiche date da TInfo, ma questo il compilatore potrebbe agevolmente verificarlo. Alla fine tutte le liste necessarie sarebbero disponibili e il compilatore sarebbe in grado di eseguire staticamente tutti i controlli di tipo.
Tutto questo in C++ e` possibile tramite il meccanismo dei template.

 

successivo
–«  INDICE  »–

 

 

 

 
Powered by paper&pencil (carta&matita ) - Copyright © 2001-2019 Cataldo Sasso