5

Tôi đang sử dụng Visual Studio 2005 Proffesional Edition.toán tử C++ typeid

Trong ví dụ sau, SomeClass là lớp được định nghĩa trong thư viện dll của bên thứ ba mà tôi đang sử dụng. SomeClass có các phương thức ảo. Tôi nhận thấy rằng typeid của toán tử cung cấp các kết quả khác nhau khi được áp dụng cho chính loại đó và khi được áp dụng cho đối tượng của kiểu đó. Đây có phải là hành vi bình thường, và nếu không phải điều gì có thể là lý do cho hành vi đó?

typeid(SomeClass).raw_name() // the value of this is "[email protected]@" 
typeid(SomeClass).name()   /// "class SomeClass" 

SomeClass obj; 
typeid(obj).raw_name(); // "[email protected]@" 
typeid(obj).name();  // "class TLomeClass" 
+2

Tỷ lệ khung hình 0%. Sẽ không trả lời câu hỏi này. Đặc biệt là sau khi tôi phát hiện ra rằng tôi đã anserred một trong những câu hỏi của bạn. :-) –

+0

câu hỏi nào :) – user152508

+0

Các câu hỏi tôi đã xem xét đã được giải quyết - để chấp nhận câu trả lời hữu ích nhất cho câu hỏi của bạn sử dụng dấu kiểm. –

Trả lời

2

Mã trong câu hỏi của bạn giống hoặc tương tự với mã bạn gặp sự cố?

Nhà điều hành typeid, khi được áp dụng cho các loại đa hình, trả về đối tượng type_info xác định loại động động của đối tượng đa hình. Vì vậy, ví dụ, nếu bạn áp dụng typeid đến một tài liệu tham khảo của loại Base & (nơi Base là đa hình), mà thực sự là ràng buộc để một đối tượng kiểu Derived (nơi Derived có nguồn gốc từ Base), đối tượng type_info trả về bởi typeid sẽ tương ứng với lớp Derived, không phải lớp học Base. Nó có thể là một cái gì đó như thế đang xảy ra trong mã của bạn?

Ngoài ra, trong một số trình biên dịch (như MS Visual Studio) để sử dụng đầy đủ chức năng typeid, như được mô tả ở trên, bạn cần phải biên dịch mã của bạn với Run-Time Type Information (RTTI) được kích hoạt. Có lẽ sự vắng mặt của RTTI đã dẫn đến những hiệu ứng kỳ lạ mà bạn quan sát được.

P.S. Trái ngược với những gì được nêu trong câu trả lời hiện được chấp nhận, typeid là tính năng chuẩn C++ hoàn chỉnh và hoàn hảo. Nó không phải là một phần mở rộng của trình biên dịch.

+0

Có, bạn đã đúng. Trong ví dụ của tôi, tôi đã có một hàm thư viện trả về con trỏ cơ sở trỏ đến đối tượng lớp dẫn xuất. Tuy nhiên, chữ ký của hàm này là hàm Base *(), và trong tài liệu thư viện, lớp cơ sở apperead là lớp lá, tức là không có lớp nào được xác định để kế thừa từ nó. Nhưng tôi đoán vậy, rằng hàm thực sự đã trả về một con trỏ trỏ đến lớp dẫn xuất nhiều hơn mà không được nói trong tài liệu libary. I.e nếu tôi nói điều này: Base baseObj; Base * basePtr = fucntion(); sau đó tuyên bố sau là đúng typeof (baseObj)! = Typeof (* basePtr) – user152508

1

Lý do cho hành vi này được ghi lại ở đâu đó on MSDN. Hành vi cụ thể mà bạn đang thấy trong trường hợp cụ thể này có thể là do một số sử dụng thừa kế, hoặc một số phần mở rộng của trình biên dịch, không được tài liệu bởi nhà cung cấp .DLL.

Hành vi của nhà điều hành không được xác định theo tiêu chuẩn C++ và do đó là phần mở rộng của trình biên dịch. Bạn không thể dựa vào hành vi của nó, cũng như bạn có thể có bất kỳ kỳ vọng hợp lý nào để tìm ra lý do tại sao nó hoạt động theo cách nó thực hiện, trừ khi nó được ghi rõ ràng bởi nhà cung cấp. Hành vi của nó có thể đã thay đổi trong VS2008, và có khả năng khác với VS2003. (Nó chắc chắn khác với GCC, ICC và các trình biên dịch khác.)

+0

Cảm ơn bạn đã trả lời.Điều này giúp tôi rất nhiều. Trên thực tế, sau khi một số điều tra, tôi đi đến kết luận rằng các nhà cung cấp có một số tương lai không có giấy tờ của lớp học cụ thể. – user152508

+0

Tôi xin lỗi: cái gì? !!! Toán tử 'typeid' được định nghĩa rõ ràng và rõ ràng theo chuẩn C++. Nó không phải là một phần mở rộng của trình biên dịch. – AnT

+0

Có, typeid được xác định là 8 * trong tiêu chuẩn, nhưng hành vi * của nó * thì không. Yêu cầu rõ ràng duy nhất là: 'typename A a1, a2; assert (typeof (a1) == typeof (a2)); 'Bất cứ điều gì ngoài điều đó, bằng cách đọc của tôi, là một phần mở rộng. – greyfade