Sử dụng static_cast là tốt tại ví dụ nhưng reinterpret_cast thì không. Bởi vì reinterpret_cast không chuyển đổi vtable.
Không, vấn đề là reinterpret_cast
hoàn toàn không biết gì về di sản thừa kế. Nó sẽ chỉ trả về cùng một địa chỉ không thay đổi . Nhưng static_cast
biết rằng bạn đang thực hiện downcast: tức là truyền từ lớp cơ sở sang lớp dẫn xuất. Vì nó biết cả hai loại liên quan, nó điều chỉnh địa chỉ tương ứng, tức là, làm điều đúng.
Hãy giả vờ thực hiện của chúng tôi đưa ra các giả thuyết lớp OVERLAPPEDEX
có một hàm ảo như thế này:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr
Con trỏ chúng tôi đang đưa ra điểm đến OVERLAPPED
subobject. reinterpret_cast
sẽ không thay đổi điều đó. Nó sẽ chỉ thay đổi kiểu. Rõ ràng, việc truy cập vào lớp OVERLAPPEDEX
thông qua địa chỉ này sẽ dễ dàng tàn phá, bởi vì các vị trí của các lớp con của nó là tất cả sai rồi!
what we believe we have when we access OVERLAPPEDEX through the pointer
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------+-----+------+-----------+------+------+------+
| vptr | OVERLAPPED | AssociatedClient | ClientState | <- what we actually have
+------+------------+------------------+-------------+
^
|
ptr
static_cast
biết rằng để chuyển đổi một OVERLAPPED*
-OVERLAPPEDEX*
nó phải điều chỉnh địa chỉ, và làm điều đúng đắn:
+------+------------+------------------+-------------+
| vptr | OVERLAPPED | AssociatedClient | ClientState |
+------+------------+------------------+-------------+
^
|
ptr after static_cast
Mặc dù, nếu tôi sử dụng C-Style đúc tại đó (không reinterpret_cast), nó có thể cũng đi sai?
Một C-style cast được định nghĩa là người đầu tiên trong các thứ sau đó thành công:
const_cast
static_cast
static_cast
, sau đó const_cast
reinterpret_cast
reinterpret_cast
, sau đó const_cast
Như bạn có thể thấy, static_cast
được thử trước reinterpret_cast
, vì vậy trong trường hợp này, dàn diễn viên kiểu C cũng sẽ làm điều đúng.
More info
Không đảm bảo. Có rất ít sự bảo đảm về những gì xảy ra trên reinterpret_cast
. Tất cả các triển khai mà tôi biết sẽ chỉ cung cấp cùng một địa chỉ không thay đổi.
Tôi không hoàn toàn thông thạo C++, nhưng sự hiểu biết của tôi là "diễn giải lại" nghĩa là '* (destination_type *) &' có nghĩa là trong C. Có lẽ "tĩnh cast" thực sự có mối quan hệ lớp và cho phép trình biên dịch thực hiện công việc chuyển đổi không tầm thường. –