2014-06-18 8 views
6

Po użyciu obiektu typeid na obiekcie polimorficznym, myślę, że obiekt musi być zdefiniowany (a nie tylko deklaracja), ponieważ operacja musi uzyskać informacje o obiekcie pod adresem runtime. Oto mój kod:W przypadku użycia parametru typid na obiekcie polimorficznym należy go zdefiniować?

#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; 
} 

I z clang 3.4, mam błąd link:

undefined reference to `d'

Ale z g++ 4.8.1, to działa dobrze i mam wynik:

1D
8

Moje pytanie :

  1. Który jest poprawny?
  2. W jaki sposób g ++ implementuje typeid? Jak uzyskać informacje z obiektu polimorficznego bez definicji?
+2

Nie wiem, który z nich jest poprawny, ale [g ++ ma błąd linkera] (http://coliru.stacked-crooked.com/a/288ddd8f4e70f535) z 'extern D & d'. Więc być może g ++ jest na tyle sprytny, aby zorientować się, że 'd' musi być typu' D' (biorąc pod uwagę, że nie jest wskaźnikiem ani referencją) –

+0

@BryanChen Ale może nie jest dozwolone przez standard ...? – songyuanyao

+1

Myślę, że powodem, dla którego g ++ wydaje się działać dobrze, jest typ 'd'. Jest * statycznie * 'D', więc kompilator zna typ' d', i być może g ++ zoptymalizował kod, aby uzyskać 'typeinfo' of' d' w środowisku wykonawczym. Jednakże, jeśli typ 'd' jest' D & 'lub' D * ', kompilator nie zna swojego ** typu w czasie kompilacji **, więc nie może zoptymalizować kodu. – ikh

Odpowiedz

2

Od 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.

Brzmi jak dzyń 3.4 ma rację.

Aktualizacja

Norma mówi:

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).

To jest nieco inny od języka używanego przez cppreference.com ale nadal wskazuje Clang 3.4 jest w porządku.

+0

Sformułowanie "ocenia wyrażenie" faktycznie nie pojawia się w standardzie. – Brian

+0

Jak to się mówi, że klang ma rację? – Brian

+0

@ Brian, jeśli wyrażenie jest typu polimorficznego, nie rozumiem, w jaki sposób kompilator może wydedukować informacje o typie w czasie kompilacji, co g ++ jest w stanie w jakiś sposób odciąć. –

Powiązane problemy