2014-06-18 40 views
6

在一個多態對象上使用typeid時,我認爲該對象必須被定義(不僅僅是一個聲明),因爲typeid操作需要獲取對象的信息在運行時。這裏是我的代碼:在多態對象上使用typeid時,是否必須定義它?

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

而且隨着clang 3.4,我得到了鏈接錯誤:

undefined reference to `d'

但隨着g++ 4.8.1,它工作得很好,我得到的結果是:

1D
8

我的問題:

  1. 哪一個是對的?
  2. g ++如何實現typeid?它如何從沒有定義的多態對象中獲取信息?
+2

我不知道哪一個是正確的,但是[g ++得到鏈接器錯誤](http://coliru.stacked-crooked.com/a/288ddd8f4e70f535)與'extern D&d'。所以也許g ++足夠聰明,可以發現'd'必須是'D'類型(因爲它不是指針或參考) –

+0

@BryanChen但是標準中可能不允許? – songyuanyao

+1

我認爲g ++似乎很好的原因是'd'的類型。它*是靜態*'D',因此編譯器知道'd'的類型,並且可能g ++優化了代碼以在運行時獲得'd'的'typeinfo'。但是,如果'd'的類型是'D&'或'D *',編譯器在編譯時**不知道它的類型**,所以它不能優化代碼。 – ikh

回答

2

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.

聽起來鏗鏘3.4是正確的。

更新

的標準說:

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

它是由cppreference.com使用的語言略有不同,但它仍指向鐺3.4是正確的。

+0

措辭「評估表達式」實際上並未出現在標準中。 – Brian

+0

它是如何指向鐺是正確的? – Brian

+0

@Brian,如果表達式求值爲一個多態類型,我不明白編譯器如何在編譯時推導出類型信息,哪個g ++能夠如何實現。 –

相關問題