Newsgroup: it.comp.lang.c++
Titolo: aiuto per progettazione classe con numero di campi variabile.

Dovrei gestire un entità che può avere un numero di campi variabile.
Ognuno di questi campi è rappresentato come un numero (intero o float).
faccio un esempio che non è quello reale...(ci metterei troppo a spiegare
qualcosa che non nteressa):
l'elemento può essere un 'gene'
i campi possono essere:
"ha l'elemento x" che può assumere solo 0 oppure 1
"lunghezza dell'eleica" un intero!
"maschi o femmina" che può assumere 1 oppure 2
"anno dell'individuo" intero!
"varianza..." float
devo creare una struttura (classe, struct o altro) che rappresenti il "gene"
a priori non conosco il numero  campi e il tipo.
Per questo ci sono due file.
In uno c'è il nome del campo ed il tipo (che può essere float oppure se è
intero ha il minimo ed il massimo valore assunto da quel campo)
esempio
anno 0 120
sesso 1 2
varianza float
elementox  0 1
...
...
in un altro file ci sono i dati: un gene per ogni riga.
nella riga ci sono i numeri che rappresentano i valori dei campi indicati
nel file di prima (nello stesso ordine).
La struttura dati deve ospitare i dati e poi restituire il valore di ogni
elemento richiesto
es. int sesso=gene.restituisci_elemento_della_colonna(2); //restituisce il
secondo elemento.
Mi piacerebbe manipolare 'gene' anche con i vector.
Cosa mi consigliate?
Grazie ina tncipo, Mario.


Certo che se effettivamente il tipo e i numeri dei campi possono variare in
modo non prevedibile, il problema si complica. Perņ se possiamo fare
l'ipotesi di poter prevedere tutti i campi possibili per ogni gene (e quindi
anche i tipi associati ai campi), abbiamo una buona semplificazione.
In questo caso, innanzitutto possiamo supporre di avere un vector di oggetti
"Gene", in modo da poterci accedere come hai detto tu, in modo diretto.
Ogni oggetto Gene č composto da tutti i possibili campi (attributi) che puņ
avere un gene.
struct Gene {
int anno;
int lunghezza;
int sesso;
float varianza;
bool elementox;
//... tutti i possibili campi
NuovoGene() {//inizializzazione, usa dei valori di default
 anno = 0;
 lunghezza = 0;
 sesso = 1;
 varianza =0.0;
 elementox=0;
//... tutti i possibili campi}
};
Quando leggi da file farai (in metalinguaggio):
while (ci sono altri geni)  {
    Gene g;
    g.NuovoGene(); //questa funzione potrebbe essere anche inutile se si č
sicuri di leggere tutti i campi possibili per il gene nel secondo file
    g.anno =  LeggiAnno();
    g.lunghezza = LeggiLunghezza();
            ...
    g.elementox = LeggiElementoX();
}
Se invece il numero il nome e il tipo dei campi č "proprio" variabile allora
si potrebbe pensare a qualcosa del genere:
Soluz.2
class Field
{
public:
    Field (const std::string& value):Value(value) {...}
    ~Field() {...}
    int GetIntValue() {
        return ((int)atoi(Value.c_str());
    }
    float GetFloatValue() {
        return ((float)atof(Value.c_str());
    }
    bool GetBoolValue() {
        return ((bool)atoi(Value.c_str());
    }
private:
    std::string Value;
};
class Gene {
public:
 Gene(){...}
~Gene(){...}
void InserisciField(const std::string& nome, const Field& f) {
...
FieldsMap.insert(std::make_pair(nome, f));
}
Field& GetField(const std::string& nome) {
...
    return (m_FieldsMap.find(nome)->second);
}
private:
    std::map<std::string, Field> FieldsMap;  //key:nome campo, value: valore
campo
}
Quando leggi dal file 1, ti ricavi il tipo del campo e dal file 2 ti ricavi
il valore:
while (ci sono altri geni)  {
Gene g;
std::string nome = LeggiNome(); //dal file 1
std::string value = LeggiValue(); //dal file 2
Field f(value);
g.InserisciField(nome, f);
...
}
E poi ti crei un vector di oggetti Gene come nell'altra soluzione.
std::vector<Gene> VettoreGeni;
Se vuoi usare un campo di un gene ad esempio farai:
bool elementox = VettoreGeni[i].GetField("elementox").GetBoolValue();
Ciao Andrea

 [CUT]
Aggiungo alle soluzioni di Andrea una ulteriore, forse un po' piu' 
sporca: se i file sono noti e fissi _prima_ della compilazione del 
programma, allora si puo' scrivere un programma che generi i file header 
e implementazione che corrispondano alle strutture descritte nei file 
dati, e quindi compilarne il risultato.
-- 
Mat/tia Belletti - Undergraduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://www.cs.unibo.it/~mbellett
Linux registered user 299762 @ Linux registered machine 213003