I dizionari sono quello che suggerisce il loro nome: delle memorie associative chiave/valore. Sia la chiave che il valore possono essere oggetti generici. I dizionari sono implementati internamente come tabelle di hashing e di conseguenza sono estemamente veloci ed efficaci nel reperire i dati. Le tabelle di hashing sono a tuttoggi la struttura piu' veloce conosciuta per memorizzare e reperire dati tramite chiavi. I dizionari manipolano un dato particolare, esso stesso prodotto da alcune classi template ovvero le associazioni. Le associazioni incapsulano il concetto di legame fra chiave e corrispettivo valore.
Anche per i dizionari esiste un concetto di dizionario diretto e indiretto, a seconda che vengano memorizzati istanze o pointer di classi associazione. Le associazioni sono presenti in quattro varianti per consentire di utilizzare chiavi e valori sia come oggetti che come puntatori a oggetti. Le associazioni che mantengono puntatori NON distruggono gli oggetti puntati nel loro distruttore. Comunque questi vengono distrutti dai distruttori dei dizionari.
TDictionary<T> Dizionario di oggetti di tipo TXXAssociation
TIDictionary<T> Dizionario di puntatori a oggetti di tipo TXXAssociation
TDDAssociation<K,V> Associazione di oggetto chiave e di oggetto valore
TDIAssociation<K,V> Associazione di oggetto chiave e di puntatore a oggetto valore
TIDAssociation<K,V> Associazione di puntatore a oggetto chiave e di oggetto valore
TIIAssociation<K,V> Associazione di puntatorea a chiave e puntatore a valore
Gli oggetti chiave devono definire una funzione int HashValue() oppure deve esistere una funzione 'int HashValue(const T& s)' affinche' sia possibile inserirli e recuperarli in una tabella di hashing. Questa funzione deve restituire un intero a piacere ma il piu' possibile diverso a seconda dei valori chiave.
Nella libreria esistono due comode funzioni: stringHash(const char*) e stringHashNocase(const char*) per ricavare il volore di hash di stringhe.
Sia la chiave che il valore associato sono memorizzati in modo diretto. Il dizionario usato e' comunque indiretto.
...
inline int HashValue(const FixString& s) {return stringHash(s);}
...
typedef TDDAssociation<FixString, double> varAssoc;
TIDictionary<varAssoc> variableHolder;
...
void saveValue(const char* key, double val)
{
variableHolder.Add(new varAssoc(key, val));
}
...
double getValue(const char* key)
{
varAssoc search(key, 0);
varAssoc* rv = variableHolder.Find();
return rv ? rv->Value() : 0.0;
}
...
...
In questo esempio la chiave e' memorizzata in modo indiretto, il valore in modo diretto. Il dizionario usato e' comunque indiretto.
...
class myKey
{
public:
char name[80];
int typeIndex;
myKey(const char* pname, int ptypeIndex) {
strncpy(name, pname, sizeof(name));
typeIndex = ptypeIndex;
}
int operator==( const myKey& c ) const {
typeIndex == c.typeIndex && !strcmp(name, c.name);
}
int HashValue() const {
return ::stringHash(name) + typeIndex;
}
};
...
typedef TIDAssociation<myKey, double> varAssoc;
TIDictionary<varAssoc> variableHolder;
...
void saveValue(const char* name, int typeIndex, double val)
{
variableHolder.Add(new varAssoc(new myKey(name, typeIndex), val));
}
...
double getValue(const char* name, int typeIndex)
{
myKey key(name, typeIndex)
varAssoc search(, 0);
varAssoc* rv = variableHolder.Find();
return rv ? rv->Value() : 0.0;
}
...
...
Per un esempio piu' completo vedi il file propertycontainer.cpp.