Hãy xem bố cục lớp của hai trường hợp.
Nếu không có ảo, bạn có hai lớp cơ sở ("X" và "Y") với mỗi số nguyên và mỗi lớp đó được tích hợp vào lớp cơ sở "Cơ sở" cũng có số nguyên. Đó là 4 số nguyên, mỗi bit 32 bit, tổng cộng 16 byte của bạn.
Offset Size Type Scope Name
0 4 int Base a
4 4 int X x
8 4 int Base a
12 4 int Y y
16 size (Z members would come at the end)
(Edit:. Tôi đã viết một chương trình trong DJGPP để có được cách bố trí và tinh chỉnh bảng để giải thích cho nó)
Bây giờ hãy nói về các lớp cơ sở ảo: họ thay thế các ví dụ thực tế của lớp với một con trỏ tới một cá thể được chia sẻ. Lớp "Z" của bạn chỉ có một lớp "Base" và cả hai trường hợp "X" và "Y" đều trỏ vào lớp đó. Do đó, bạn có số nguyên trong X, Y và Z, nhưng bạn chỉ có số nguyên Z. Điều đó có nghĩa là bạn có ba số nguyên hoặc 12 byte. Nhưng X và Y cũng có một con trỏ để chia sẻ Z (nếu không họ sẽ không biết nơi để tìm thấy nó). Trên máy 32 bit, hai con trỏ sẽ bổ sung thêm 8 byte. Điều này tổng cộng 20 mà bạn nhìn thấy. Bố trí bộ nhớ có thể trông giống như thế này (Tôi chưa xác minh nó ... ARM có ví dụ về thứ tự là X, Y, Z, rồi Cơ sở):
Offset Size Type Scope Name Value (sort of)
0 4 Base offset X ? 16 (or ptr to vtable)
4 4 int X x
8 4 Base offset Y ? 16 (or ptr to vtable)
12 4 int Y y
16 4 int Base a
20 size (Z members would come before the Base)
Vì vậy, sự khác biệt bộ nhớ là kết hợp hai thứ: một số nguyên ít hơn và hai con trỏ khác. Trái với câu trả lời khác, tôi không tin vtables trả bất kỳ (chỉnh sửa) trực tiếp (/ chỉnh sửa) cuộn trong này, vì không có chức năng ảo.
Chỉnh sửa: ppinsider đã cung cấp thêm thông tin về trường hợp gcc, trong đó ông chứng minh rằng gcc triển khai con trỏ đến lớp cơ sở ảo bằng cách sử dụng vtable trống khác (tức là, không có hàm ảo). Bằng cách đó, nếu có các hàm ảo, nó sẽ không yêu cầu một con trỏ bổ sung trong cá thể lớp, đòi hỏi nhiều bộ nhớ hơn. Tôi nghi ngờ nhược điểm là một hướng dẫn bổ sung để đến lớp cơ sở.
Chúng tôi có thể mong đợi tất cả các trình biên dịch để thực hiện việc này, nhưng có lẽ không. Trang ARM thảo luận về các lớp cơ sở ảo mà không đề cập đến vtables. Cụ thể là địa chỉ các lớp cơ sở ảo với các hàm ảo và có sơ đồ chỉ ra một bố cục bộ nhớ, nơi có các con trỏ từ các phần X và Y tách biệt với các con trỏ đến vtable. Tôi khuyên mọi người không nên cho rằng con trỏ tới Base sẽ được thực hiện dưới dạng bảng.
Đánh dấu, bạn tạo bố cục đó như thế nào? –
Nếu bạn có nghĩa là định dạng bảng, nó chỉ là mã. Tôi chỉ đoán được nội dung. Tôi sẽ chỉnh sửa câu trả lời của mình với nhiều chi tiết hơn và tham khảo câu trả lời của ppinsider. – markets
tôi rất thích đọc nó. cảm ơn +1 –