Newsgroup: it.comp.lang.c++
Titolo: dynamic_cast

Vorrei sapere se e' possibile calcolare il tipo di una classe a run-time.
Ad esempio se ho il prorgamma (+ o - programma :) )
#include <vector>
std::vector<int> va,vb;
class CA {
 public:
  int a;
  CA (){
  a=-1;};
};
class CB {
 public:
  int b;
  CB (){
    b=1;};
};
int calcolaTipo(void * t){
  if (tipo(t) e' CA) return 1;
  else return -1;
}
int main(){
  CA ia;
  CB ib;
 return calcolaTipo(ia);
}
come posso scrivere la funzione calcolaTipo?
Grazie.


int calcolaTipo(void * t){
   if (dynamic_cast<CA*>(t)!=NULL) return 1;
   else return -1;
}
Non l'ho pero' provato... e ho il dubbio che non te lo compili, dicendo 
che void* non e' un tipo base valido per fare l'operazione. Bisognerebbe 
andare a controllare cosa dice lo standard (ammesso poi che il tuo 
compilatore lo rispetti).
Se non va, puoi fare una classe base dalla quale CA e CB derivino ed 
usare un puntatore a tale classe, invece che void*t; cosi' sono sicuro 
che funzioni.
Un'altra alternativa e' l'uso di typeof:
int calcolaTipo(void * t){
   if (typeid(*t)==typeid(CA)) return 1;
   else return -1;
}
*ATTENZIONE*
C'e' un importante differenza tra i due approcci: col primo, passando un 
puntatore ad un oggetto di classe derivata da CA, ti restituisce 1, col 
secondo -1; ovvero typeid controlla che sia proprio CA, non una sua 
derivazione.
  bye
	av.

Ho cercato di sfruttare il typeid con il seguente codice
#include <vector>
#include <stdio.h>
#include <typeinfo>
#include <iostream.h>
std::vector<int> va,vb;
class CA {
 public:
  int a;
  CA (){
  a=-1;};
};
class CB {
 public:
  int b;
  CB (){
    b=1;};
};
int calcolaTipo(void * t){
  static int i=0;
  i++;
  printf(" VAI: %i\n",i);
  std::cout << "tipo mio: " << typeid(t).name() << std::endl;
  std::cout << "tipo CA: " << typeid(CA).name() << std::endl;
    std::cout << "tipo CB: " << typeid(CB).name() << std::endl;
   if (typeid(t)==typeid(CA)) return 1; else return -1;
 
}
int main(){
  CA ia;
  CB ib;
  printf(" ****************\n");
  printf(" CASO 1: \n");
  std::cout << "tipo da pasasre: " << typeid(ia).name() << std::endl;
  printf("Valore di ritorno %i\n",calcolaTipo(&ia));
  printf(" ****************\n");
  printf(" CASO 2: \n");
  std::cout << "tipo da pasasre: " << typeid(ib).name() << std::endl;
  printf("Valore di ritorno %i\n",calcolaTipo(&ib));
 
 return 0;
}
ed ho ottenuto, sigh :(, il seguente risultato:
 ****************
 CASO 1: 
tipo da pasasre: 2CA
 VAI: 1
tipo mio: Pv
tipo CA: 2CA
tipo CB: 2CB
Valore di ritorno -1
 ****************
 CASO 2: 
tipo da pasasre: 2CB
 VAI: 2
tipo mio: Pv
tipo CA: 2CA
tipo CB: 2CB
Valore di ritorno -1
ciao


Sei sicuro di avere l'RTTI attivato?
Sia gcc, che Visual C++ (almeno la 6), hanno uno switch apposta, di 
default e' spento.
  bye
	av.

 
Se sapessi esattamente cos'e' potrei rispondere. Su g++ come si attiva
(sto cercando sul manuale... )
Cosa fa di preciso? A volte il gdb ci si imbroglia un po' sopra.
Grazie, Marco

 Cosa fa di preciso? A volte il gdb ci si imbroglia un po' sopra.
Ho riguardato il manuale e devo dire che mi sono sbagliato: e' abilitato 
di default sulle versioni recenti (ero rimasto alla 2.8).
Per disattivarlo si usa -fno-rtti, al che immagino che, se non e' gia' 
attivato, si debba usare -frtti.
Altrimenti non ti so piu' aiutare. :(
Posso solo suggerirti, di nuovo, di provare con una classe base comune e 
sostituire il void* con un puntatore a tale classe.
  bye
	av.

     av.
-- 
There are better things in life than alcohol, but alcohol makes up for 
not having them. - Terry Pratchett.

Palmiro Bogomil Ganjins di Boscopelo wrote:
Prova con qualcosa del tipo (ammesso che nel tuo caso si possa fare):
template <class T>
int calcolaTipo(T * t){
    if (typeid(*t)==typeid(CA)) return 1;
    else return -1;
}
Ma se usi una template function il passo successivo che puoi fare e` 
evitare il passaggio per l'RTTI e fare il tutto compile time.
Alternativa: crei una classe padre virtuale da cui derivi entrambe e 
metti come tipo del parametro di calcolaTipo proprio questa classe, aa 
quel punto puoi usare il dynamic_cast del subject.
Bye,
  Gabry