Nhiều kế thừa làm cho điều đó không đúng sự thật.
Điều đó không hoàn toàn chính xác. Xem xét ví dụ này:
struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};
Khi tạo một thể hiện của D, Bvà Cđược khởi tạo mỗi dụ tương ứng của họ A. Tuy nhiên, sẽ không có vấn đề gì nếu trường hợp Dcó cùng địa chỉ của thể hiện của Bnó và thể hiện tương ứng của nó A. Mặc dù không bắt buộc, đây chính xác là những gì xảy ra khi biên dịch với clang 11và gcc 10:
D: 0x7fffe08b4758 // address of instance of D
B: 0x7fffe08b4758 and A: 0x7fffe08b4758 // same address for B and A
C: 0x7fffe08b4760 and A: 0x7fffe08b4760 // other address for C and A
Liệu thừa kế ảo cũng làm cho điều đó không đúng sự thật
Hãy xem xét một phiên bản sửa đổi của ví dụ trên:
struct A {};
struct B : virtual A {};
struct C : virtual A {};
struct D : B, C {};
Sử dụng công virtualcụ xác định chức năng thường được sử dụng để tránh các cuộc gọi chức năng mơ hồ. Do đó, khi sử dụng tính virtualkế thừa, cả hai Bvà các Cthể hiện phải tạo một Athể hiện chung . Khi bắt đầu D, chúng tôi nhận được các địa chỉ sau:
D: 0x7ffc164eefd0
B: 0x7ffc164eefd0 and A: 0x7ffc164eefd0 // again, address of A and B = address of D
C: 0x7ffc164eefd8 and A: 0x7ffc164eefd0 // A has the same address as before (common instance)
Mã sau đây có đúng không
Không có lý do ở đây để sử dụng reinterpret_cast, thậm chí nhiều hơn, nó dẫn đến hành vi không xác định. Sử dụng static_castthay thế:
A* pA = static_cast<A*>(pB);
Cả hai diễn viên hành xử khác nhau trong ví dụ này. Các reinterpret_castsẽ diễn giải lại pBnhư một con trỏ đến A, nhưng con trỏ pAcó thể trỏ đến một địa chỉ khác nhau, như trong ví dụ trên (C vs A). Con trỏ sẽ được cập nhật chính xác nếu bạn sử dụng static_cast.
reinterpret_castvới các lớp luôn tanh (ngoại trừ từ lớp này sang lớp khácvoid*và trở lại cùng lớp).