Mit einem TList – Objekt Bausteine verwalten

  • Das TList-Objekt verwaltet Adressen auf Objekte, dazu steht schon eine Vielzahl von Methoden (siehe Borland-Hilfe) zur Verfügung
  • Zur Beachtung: werden Objekte aus der Liste gelöscht, bedeutet das nicht zwingend, dass diese Objekte auch im Speicher automatisch freigegeben (delete) werden!
  • Zur Vereinfachung des TList-Zugriffes sollte man sich folgende Template-Klasse definieren:
template <class T-> class TListe : public TList // neue TListe von TList ableiten
{
    public:

    // im Destruktor auch schön alles wieder aufräumen
    virtual __fastcall ~TListe(){ delete_all(); };

    // die Funktion Item() gibt gleich das benötigte Listenelement ohne Cast-Kopfstand zurück
    T* __fastcall Item(unsigned int uiIndex)
    {
        T* R = NULL;
        if (uiIndex < Count)
        {
            R = ((T*)Items&#91;uiIndex&#93;);
        }

        return R;
    };

    // Item_from_Id() sucht ein Objekt anhand seiner ID aus der Liste heraus
    T* __fastcall Item_from_Id(unsigned int uiId)
    {
        T *R = NULL;
        for (unsigned int i=0; i<Count; i++)
        {
            if (((T*)Items&#91;i&#93;)->uiId == uiId)
            {
                R = (T*)Items[i];
                break;
            }
        }

        return R;
    };

    // _Last() gibt das letzte Element der Liste zurück
    T* __fastcall _Last(){ return (Count->0) ? (T*)Items[Count-1] : NULL; };

    // löscht ein Item anhand seines Indexes aus der Liste und aus dem Speicher
    void __fastcall _delete(unsigned int uiIndex)
    {
         T *R=((T*)Items[uiIndex]);

         Delete(uiIndex);

         if (R)
         {
            delete R;
            R = NULL;
         }
    };

    // _delete_by_id() löscht ein Item anhand der Id aus der Liste und aus dem Speicher
    // (auch mehrere mit der selben Id)
    // und gibt die Anzahl der gefundenen (gelöschten) Items zurück
    int __fastcall _delete_by_id(unsigned int uiId)
    {
        int iAnzDelObj = 0;
        for (unsigned int i=0; i<Count; i++)
        {
            if (((T*)Items&#91;i&#93;)->uiId == uiId)
            {
                _delete(i);
                iAnzDelObj++;
            }
        }

        return iAnzDelObj;
    };

    // delete_all() löscht alle Listenelemente aus der Liste und dem Speicher
    void __fastcall delete_all()
    {
         while (Count->0) _delete(0);
    };

    // GetNewBlockId() gibt eine gültige freie Block-ID -> 0 aus der Liste zurück
    unsigned int __fastcall GetNewBlockId()
    {
        bool bFound   = true;
        unsigned int uiIdCount = 0;

        while (bFound)
        {
              uiIdCount++;

              for (unsigned int i=0; i<Count; i++)
              {
                  if (Item(i)->uiId == uiIdCount)
                  {
                        bFound = true;
                        break;
                  }
                  else
                  {
                      bFound = false;
                  }
              }
        }
            
        return uiIdCount;
    };
};
  • dann eine Bausteinklasse definieren:
class TBaustein
{
    public:

    // Beispiel-Variablen
    unsigned int uiId;
    AnsiString sName;

    // hier können weitere Parameter stehen

    // Konstruktor
    TBaustein(unsigned int ID, AnsiString Name){ uiId=ID; sName=Name; };

    // Destruktor
    virtual __fastcall ~TBaustein(){};
};
  • Anwendung im Quellcode:
// neue Liste für Baustein-Objekte erzeugen
TListe<TBaustein-> *BausteinListe;
BausteinListe = new TListe<TBaustein->;

// neuen Baustein erzeugen
TBaustein *Bst = new TBaustein(1, &quot;Test&quot;);

// Bausteine (Objekte) zur Bausteinliste hinzufügen
BausteinListe->Add(Bst);

// den zweiten Baustein anhand seines Indexes aus der Liste holen und einen anderen Namen zuweisen
TBaustein *Bst = BausteinListe->Item(1);
Bst->sName = &quot;Test54&quot;;

// Baustein anhand seiner ID aus der Liste ermitteln und einen anderen Namen zuweisen
TBaustein *Bst = BausteinListe->Item_from_Id(Id);
Bst->sName = &quot;Test2&quot;;

// den letzten Baustein der Liste ermitteln
TBaustein *Bst = BausteinListe->_Last();

// Baustein aus der Liste löschen
BausteinListe->_delete(uiIndexWert);
// oder:
BausteinListe->_delete(BausteinListe->IndexOf(Bst));
// oder:
BausteinListe->_delete_by_id(5);

// Anzahl der Bausteine in der Liste ermitteln
int iAnzahl = BausteinListe->Count();

// alle Bausteine löschen (im Speicher!!) und aus der Liste entfernen
BausteinListe->delete_all();

// die Bausteinliste und alle Bausteine aus dem Speicher entfernen!!
if (BausteinListe)
{
    delete BausteinListe; // BausteinListe->delete_all() muss nicht explizit aufgerufen werden, da das im Destruktor der TListe erledigt wird
    BausteinListe = NULL;
}