2015-12-18 25 views
13

Mã C++ có thể được biên dịch với thông tin loại thời gian chạy bị tắt, điều này sẽ vô hiệu hóa dynamic_cast. Tuy nhiên, các phương thức ảo (đa hình) vẫn cần phải được gửi dựa trên kiểu thời gian chạy của đích. Tuy nhiên, điều đó có nghĩa là thông tin về loại có hiện diện hay không và dynamic_cast sẽ luôn có thể hoạt động?Không có RTTI nhưng vẫn là phương pháp ảo

+1

Tôi đoán là vtable vẫn còn hiện diện nhưng vì nó không chứa bất kỳ thông tin kiểu nào (chỉ các con trỏ hàm) các chức năng ảo sẽ vẫn hoạt động. –

+1

Bản sao có thể có của http://stackoverflow.com/questions/4486609/when-can-compiling-c-without-rtti-cause-problems ...? –

+0

Để làm cho dynamic_cast hoạt động (trong trường hợp phức tạp với nhiều thừa kế), bạn cần một cái gì đó nhiều hơn các bảng chức năng ảo – marom

Trả lời

13

Tắt RTTI giết chết dynamic_casttypeid nhưng không ảnh hưởng đến chức năng ảo. Các hàm ảo được gửi qua "vtable" của các lớp có bất kỳ hàm ảo nào; nếu bạn muốn tránh việc có vtable, bạn chỉ đơn giản là không có chức năng ảo.

Rất nhiều mã C++ trong tự nhiên có thể làm việc mà không dynamic_cast và gần như tất cả của nó có thể làm việc mà không typeid, nhưng tương đối ít C ứng dụng ++ sẽ tồn tại mà không cần bất kỳ chức năng ảo (hoặc nhiều hơn vào vấn đề, chức năng mà họ dự kiến ​​sẽ được ảo trở thành không phải ảo).

Một bảng ảo (vtable) chỉ là một con trỏ trên mỗi bảng tìm kiếm cho tất cả các hàm ảo. Bạn chỉ trả tiền cho những gì bạn sử dụng (Bjarne yêu thích triết lý này, và ban đầu chống lại RTTI). Với RTTI đầy đủ, bạn kết thúc với các thư viện và thực thi của bạn có khá nhiều chuỗi phức tạp và các thông tin khác được đưa vào để mô tả tên của từng loại và có lẽ những thứ khác như quan hệ phân cấp giữa các loại.

Tôi đã thấy các hệ thống sản xuất khi vô hiệu hóa RTTI đã thu nhỏ kích thước tệp thi hành xuống 50%. Hầu hết điều này là do các tên chuỗi lớn kết thúc trong một số chương trình C++ sử dụng nhiều mẫu.

+0

Ok, do đó, 'dynamic_cast' cần thêm thông tin. Nhưng có vẻ như 'typeid' vẫn có thể hoạt động, ít nhất là đối với các loại có vtable. Con trỏ vtable có thể được truy cập thủ công từ mã C++ không? –

+0

'typeid' không thể hoạt động vì một trong những mục đích chính của nó là cung cấp tên cho từng loại, và những tên đó (các chuỗi được ngắt null thực tế) không được phát ra thành các tệp đối tượng không có RTTI. Và không, vtable không thể được truy cập theo cách thủ công theo cách di động trong C++. Có thể có những cách cụ thể cho nền tảng, nhưng ngay cả đó là IMO hiếm. –

+0

Ồ, xin lỗi tôi. :) Tôi giả định, mà không kiểm tra, rằng 'typeid' trả về một số loại số nguyên/con trỏ xiên. Làm cho cảm giác rằng nó không hoạt động nếu đó là một chuỗi (edit: thực sự 'class type_info'). –

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