2014-06-18 9 views
6

Quando si utilizza typeid su un oggetto polimorfico, penso che l'oggetto deve essere definito (non solo una dichiarazione) perché l'operazione typeid deve ottenere le informazioni dell'oggetto nel runtime . Qui è il mio codice:Quando si usa typeid su un oggetto polimorfico, deve essere definito?

#include <iostream> 
#include <typeinfo> 

class D { 
    virtual ~D() {} 
}; 
extern D d; 

int main() 
{ 
    std::cout << typeid(d).name() << std::endl; 
    std::cout << sizeof(d) << std::endl; 
} 

E con clang 3.4, ho ottenuto l'errore link:

undefined reference to `d'

Ma con g++ 4.8.1, funziona bene ed ho ottenuto il risultato:

1D
8

La mia domanda :

  1. Quale è giusto?
  2. Come implementa g ++ typeid? Come può ottenere le informazioni da un oggetto polimorfico senza definizione?
+2

Non so quale sia corretto, ma [g ++ ha errore linker] (http://coliru.stacked-crooked.com/a/288ddd8f4e70f535) con 'extern D & d'. Quindi forse g ++ è abbastanza intelligente da capire che 'd' deve essere un tipo di' D' (dato che non è un puntatore né un riferimento) –

+0

@BryanChen Ma forse non consentito dallo standard ...? – songyuanyao

+1

Penso che il motivo per cui g ++ sembra funzionare bene è il tipo di 'd'. È * staticamente * 'D', quindi il compilatore conosce il tipo di' d', e forse g ++ ha ottimizzato il codice per ottenere 'typeinfo' di' d' in runtime. Tuttavia, se il tipo di 'd' è' D & 'o' D * ', il compilatore non conosce il suo tipo ** in fase di compilazione **, quindi non può ottimizzare il codice. – ikh

risposta

2

Da http://en.cppreference.com/w/cpp/language/typeid

a) If expression is a glvalue expression that identifies an object of a polymorphic type (that is, a class that declares or inherits at least one virtual function), the typeid expression evaluates the expression and then refers to the std::type_info object that represents the dynamic type of the expression. If the result of the evaluated expression is a null pointer, an exception of type std::bad_typeid or a type derived from std::bad_typeid is thrown.

Suona come clang 3.4 è giusto.

Aggiornamento

Lo standard dice:

When typeid is applied to a glvalue expression whose type is a polymorphic class type (10.3), the result refers to a std::type_info object representing the type of the most derived object (1.8) (that is, the dynamic type) to which the glvalue refers. If the glvalue expression is obtained by applying the unary * operator to a pointer and the pointer is a null pointer value (4.10), the typeid expression throws the std::bad_typeid exception (18.7.3).

E 'leggermente diversa dalla lingua utilizzata dal cppreference.com ma punta ancora clang 3.4 essere nel giusto.

+0

La dicitura "valuta l'espressione" in realtà non appare nello standard. – Brian

+0

Come indica che il clang è giusto? – Brian

+0

@Brian, se l'espressione valuta un tipo polimorfico, non capisco come sia possibile per il compilatore dedurre le informazioni sul tipo in fase di compilazione, che g ++ è in grado di estrarre. –

Problemi correlati