Tôi biết bố cục bộ nhớ của đa kế thừa không được xác định, vì vậy tôi không nên dựa vào nó. Tuy nhiên, tôi có thể dựa vào nó trong một trường hợp đặc biệt không. Nghĩa là, một lớp chỉ có một lớp siêu "thực". Tất cả những người khác là "các lớp trống", tức là các lớp không có trường hoặc phương thức ảo (nghĩa là chúng chỉ có các phương thức không phải ảo). Trong trường hợp này, các lớp bổ sung này không nên thêm bất kỳ thứ gì vào bố cục bộ nhớ của lớp. (Nói ngắn gọn hơn, trong từ ngữ C++ 11, lớp học có bố cục tiêu chuẩn)C++ Nhiều bố trí bộ nhớ thừa kế với "Lớp trống"
Tôi có thể phỏng đoán rằng tất cả các lớp học sẽ không có bù trừ? Ví dụ .:
#include <iostream>
class X{
int a;
int b;
};
class I{};
class J{};
class Y : public I, public X, public J{};
int main(){
Y* y = new Y();
X* x = y;
I* i = y;
J* j = y;
std::cout << sizeof(Y) << std::endl
<< y << std::endl
<< x << std::endl
<< i << std::endl
<< j << std::endl;
}
Ở đây, Y
là lớp với X
là lớp cơ sở thực mà thôi. Đầu ra của chương trình (khi biên soạn trên linux với g ++ 4.6) như sau:
0x233f010
0x233f010
0x233f010
0x233f010
Như tôi đã kết luận, không có poi điều chỉnh nter. Nhưng liệu việc triển khai này có cụ thể hay không hoặc tôi có thể dựa vào nó hay không. Tức là, nếu tôi nhận được một đối tượng thuộc loại I
(và tôi chỉ biết các lớp này tồn tại), tôi có thể sử dụng một số reinterpret_cast
để truyền cho X
không?
Hy vọng của tôi là tôi có thể dựa vào nó vì thông số kỹ thuật cho biết kích thước của một đối tượng ít nhất phải là một byte. Do đó, trình biên dịch không thể chọn bố cục khác. Nếu nó sẽ bố trí I
và J
phía sau các thành viên của X
, thì kích thước của chúng sẽ bằng 0 (vì chúng không có thành viên). Vì vậy, sự lựa chọn hợp lý duy nhất là sắp xếp tất cả các lớp siêu mà không có bù đắp.
Tôi có đúng hay tôi đang chơi với đám cháy nếu tôi sử dụng reinterpret_cast từ I
đến X
tại đây?
Bố cục bộ nhớ của thừa kế, một hoặc nhiều, căn cứ trống hoặc không, không được xác định. –
Tôi muốn nói rằng bạn đang chơi với lửa, bởi vì bạn đang cố gắng tạo ra một cấu trúc rất lạ chắc chắn sẽ gây đau đớn và đau khổ cho bất cứ ai phải hiểu nó trong tương lai, ngay cả khi nó không phá vỡ khi bạn nâng cấp trình biên dịch của bạn! – Rook
may mắn, câu lệnh của bạn không còn đúng trong C++ 11, hãy xem câu trả lời :) – gexicide