2014-06-18 18 views
6

Khi sử dụng typeid trên đối tượng đa hình, tôi nghĩ đối tượng phải được xác định (không chỉ là khai báo) vì hoạt động typeid cần lấy thông tin của đối tượng tại thời gian thời gian chạy. Dưới đây là mã của tôi:Khi sử dụng typeid trên một đối tượng đa hình, nó phải được xác định?

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

Và với clang 3.4, tôi đã nhận lỗi liên kết:

undefined reference to `d'

Nhưng với g++ 4.8.1, nó hoạt động tốt và tôi đã nhận kết quả:

1D
8

Câu hỏi của tôi :

  1. Cái nào là đúng?
  2. Cách g ++ triển khai typeid? Làm thế nào nó có thể lấy thông tin từ một đối tượng đa hình mà không có định nghĩa?
+2

Tôi không biết cái nào là đúng, nhưng [g ++ có lỗi trình liên kết] (http://coliru.stacked-crooked.com/a/288ddd8f4e70f535) với 'extern D & d'. Vì vậy, có lẽ g ++ là đủ thông minh để tìm ra rằng 'd' phải là loại' D' (cho nó không phải là con trỏ cũng không tham khảo) –

+0

@BryanChen Nhưng có lẽ không được phép theo tiêu chuẩn ...? – songyuanyao

+1

Tôi nghĩ lý do tại sao g ++ dường như hoạt động tốt là kiểu 'd'. Đó là * tĩnh * 'D', do đó trình biên dịch biết loại' d', và có thể g ++ đã tối ưu hóa mã để lấy 'typeinfo' của' d' trong thời gian chạy. Tuy nhiên, nếu kiểu 'd' là' D & 'hoặc' D * ', trình biên dịch không biết kiểu của nó ** trong thời gian biên dịch **, vì vậy nó không thể tối ưu hóa mã. – ikh

Trả lời

2

Từ 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.

Âm thanh như vang 3.4 là đúng.

Cập nhật

Tiêu chuẩn nói:

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

Nó là hơi khác với ngôn ngữ được sử dụng bởi cppreference.com nhưng nó vẫn trỏ tới Clang 3.4 là đúng.

+0

Từ ngữ "đánh giá biểu thức" không thực sự xuất hiện trong tiêu chuẩn. – Brian

+0

Làm thế nào để nó trỏ đến kêu vang đúng? – Brian

+0

@Brian, nếu biểu thức đánh giá thành một loại đa hình, tôi không hiểu làm thế nào nó có thể cho trình biên dịch suy ra thông tin kiểu tại thời gian biên dịch, mà g ++ có thể một số cách kéo ra. –

Các vấn đề liên quan