Newsgroup: it.comp.lang.c++
Titolo: Puntatori void

Salve!
         ho un problemino e volevo sapere se qualcuno puo'
consigliarmi una strada per affrontarlo.
Io ho n dati e ciascuno di questi dati e' di un tipo diverso
(int,double,char*,...).  A priori pero',  non so ni quanti dati siano
ni di quale tipo e' ciascun dato. Quello che debbo fare e', nel
momento in cui conosco quanti dati ho e di che tipo sono, allocare n
variabili, ciascuna del tipo giusto, per poi passarle ad una
funzioncina che me le riempie.
Io avevo pensato di allocare n puntatori a void oppure dichiarare un
vettore di m=max(n) (diciamo che l'insieme degli n possibili sia
limitato superiormente),
void* dati[m];
Per poi, se ad esempio il primo dato sia un intero, fare una cosa del
genere:
dati[0]= new int;
Fin qui' non mi sembra che ci sia niente di illegale il punto e' che
purtroppo ho 'scoperto' :) che non si puo dereferenziare poi dati[0],
o meglio non posso fare una cosa del tipo *(dati[0])=1;
Essendomi reso conto che sui puntatori a void non ci avevo capito un
c, mi chiedo: "Ma allora a che servono?".
A parte schersi, se qualcuno mi puo' consigliare un metodo qualsiasi
per risolvere il mio problemino gli saro' grato.
Grazie!
Per Rispondere in E-Mail  togliere - - - dall'indirizzo
                                                        Riccardo

c, mi chiedo: "Ma allora a che servono?".
Servono in quanto puntatori generici... ad esempio e` il tipo restituito da malloc
Semplicemente nel tuo caso, utilizzati in quel modo, servono a poco.
Paolo
----------------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
  e-mail: 
mar...@cli.di.unipi.it
 
----------------------------------------------------------


Se ho capito per andare a rileggere i dati debbo scorrere tutte le k
liste...
Premettendo che da quando ho fatto qualche piccola esperienza con il
lisp sono un po' allergico alle liste... come faccio poi a sapere
qual'era l'iesimo dato?
Ciao e grazie! 


come faccio poi a sapere qual'era l'iesimo dato?
Questo in effetti e` un problema, ci avevo pensato quando ho descritto questa soluzione, pero`
dato che non avevi accennato alla questione non mi sono posto il problema.
A questo punto trovare una soluzione richiederebbe la conoscenza delle possibili operazioni
che possono essere eseguite sui valori. 
Se fossero sufficientemente generiche potresti incapsularle in una classe base che poi
specializzeresti per ogni possibile tipo. Si utilizzerebbe una lista di puntatori alla classe base
e si sfrutterebbe il polimorfismo. Il cast in questo caso sarebbe incapsulato nella classe derivata.
Comunque e` una soluzione che puo` non essere facilmente adottabile.


Grazie!


 funzioncina che me le riempie.
   Salve,
	la soluzione con i puntatori e' corretta;infatti e' possibile definire un
tipo
typedef void* Boh;
Boh vari[10];
e poi aggiungere e togliere elementi dall'array vari[10] utilizzando il
reinterpret_cast, operatore che mi consente la conversione di qualunque
puntatore in un puntatore di un altro tipo;
tipo_effettivo x;
vari[0]=reinterpret_cast<Boh>(&x);
tipo_effettivo *px;
px=reinterpret_cast<void*>(vari[0]); 
 Il problema è che questa soluzione non e' type safe ovvero se io inserisco
un int e prelevo il rsiultato come se fosse un char in C++ non ha nulla da
obiettare mentre la funzione a cui passo il risultato obietta eccome
restituendomi nel migliore dei casi un risultato errato o con un break del
programma.
	Una soluzione stilisticamente migliore specie dal punto di vista della
sicurezza e' la tagged union ovvero l'utilizzo del record con varianti che
mi realizza l'unione del tipo corretto e di un tag di tipo:
enum tipotag {tip_int,tip_float,tip_double,...};
class Boh {
tipotag tag;
union{
int val_int;
float val_float;
...
};
};
  Definendo le funzioni membro della classe che permettono di prelevare e
inserire valori ho risolto il problema.
Un'ennesima soluzione che consente la massima sicurezza e genericità e'
l'uso dei template.
.