2013-08-09 6 views
7

Non riesco a ottenere correttamente la funzione di tipo. Mi sto perdendo qualcosaTypeid non funziona correttamente

Codice:

class A 
{ 
    public: 
    int a1; 
    A() 
    { 
    } 
}; 


class B: public A 
{ 
    public: 
    int b1; 
    B() 
    { 
    } 
}; 


int main() 
{ 
    B tempb; 
    A tempa; 
    A * ptempa; 
    ptempa = &tempb; 

    std::cout << typeid(tempb).name() << std::endl; 
    std::cout << typeid(tempa).name() << std::endl; 
    std::cout << typeid(*ptempa).name() << std::endl; 

    return 0; 
} 

E 'sempre stampe:

Classe B Classe A Classe A

Sto usando VS2010 per il mio progetto

+0

Si comporta allo stesso modo con Clang 4.2. Sono d'accordo che sembra sbagliato.Dalla definizione di documentazione typeid fornisce il tipo di ciò che è puntato non il tipo del puntatore. Mi dispiace non è di aiuto. Supporto morale ... –

risposta

9

L'oggetto a cui punta deve essere polimorfico affinché funzioni come previsto. Se A disponesse di metodi virtual, il codice funzionerebbe come previsto, ad esempio aggiungendo un distruttore virtuale, che I demo live here using gcc.

Quota formare il C++ draft standard sezione 5.2.8 identificazione Tipo paragrafo dice:

Quando typeid viene applicata a un'espressione glvalue cui tipo è un tipo di classe polimorfica (10.3), il risultato si riferisce a un oggetto std :: type_info che rappresenta il tipo dell'oggetto più derivato (1.8) [...]

Che si applica al caso in cui abbiamo un metodo di virtual, nel tuo caso non si dispone di un tipo polimorfico così paragrafo applica:

Quando typeid viene applicato ad un'espressione che non sia un glvalue di un tipo polimorfico classe , il risultato si riferisce a uno std :: type_info oggetto che rappresenta il tipo statico dell'espressione

Così si otterrà il static tipo di retro che è A.

solo essere un po 'più completa sezione 10.3funzioni virtuali dice:

funzioni virtuali supportano binding dinamico e programmazione orientata agli oggetti . Una classe che dichiara o eredita una funzione virtuale è chiamata classe polimorfica.

20

Il il problema è che A non ha funzioni virtuali, quindi non è trattato come un polimorfico genere. Di conseguenza, typeid cerca il tipo dichiarato del puntatore, non il tipo effettivo dell'oggetto a cui punta.

+0

Ahham. Buono a sapersi! (E avevi ragione, il 'dynamic_cast <>' non è nemmeno compilato. –

+0

Per lo meno, qualsiasi classe che è stata progettata per essere ereditata dovrebbe avere il suo dtor virtuale. Quindi chiamerei il design di OP errato. – KitsuneYMG

+0

@KitsuneYMG - 'std :: iterator' è progettato per essere derivato e non ha un distruttore virtuale.E questo è il modo in cui dovrebbe essere. –

0

Dopo aver riflettuto mentre si falcia il prato ... Un puntatore non può sapere a quale tipo di oggetto punta. Le informazioni sul tipo sono memorizzate con il puntatore e questo non viene modificato puntando su una classe derivata (B). Quindi è necessario un typecast per cambiare il tipo di puntatore e l'output IS come previsto.