Cả static_cast và reinterpret_cast dường như hoạt động tốt để truyền void * sang loại con trỏ khác. Có một lý do tốt để ủng hộ cái này hơn cái kia?
Cả static_cast và reinterpret_cast dường như hoạt động tốt để truyền void * sang loại con trỏ khác. Có một lý do tốt để ủng hộ cái này hơn cái kia?
Câu trả lời:
Sử dụngstatic_cast
: đó là diễn viên hẹp nhất mô tả chính xác những gì chuyển đổi được thực hiện ở đây.
Có một quan niệm sai lầm rằng sử dụng reinterpret_cast
sẽ là một kết hợp tốt hơn bởi vì điều đó có nghĩa là hoàn toàn bỏ qua loại an toàn và chỉ chuyển từ A sang B.
Tuy nhiên, điều này không thực sự mô tả hiệu quả của a reinterpret_cast
. Thay vào đó, reinterpret_cast
có một số ý nghĩa, đối với tất cả trong số đó cho rằng bản đồ được thực hiện bởi reinterpret_cast
định nghĩa được triển khai. [5.2.10.3]
Nhưng trong trường hợp cụ thể của việc đúc từ void*
đếnT*
ánh xạ thì hoàn toàn được xác định rõ bởi tiêu chuẩn; cụ thể là để gán một loại cho một con trỏ không chữ mà không thay đổi địa chỉ của nó.
Đây là một lý do để thích static_cast
.
Ngoài ra, và quan trọng hơn, là thực tế là mọi việc sử dụng reinterpret_cast
đều hết sức nguy hiểm vì nó chuyển đổi bất cứ thứ gì thực sự khác (đối với con trỏ), trong khi static_cast
hạn chế hơn nhiều, do đó cung cấp mức độ bảo vệ tốt hơn. Điều này đã cứu tôi khỏi các lỗi mà tôi vô tình cố gắng ép một loại con trỏ vào một loại khác.
Đây là một câu hỏi khó. Một mặt, Konrad đưa ra một quan điểm tuyệt vời về định nghĩa đặc tả cho reinterpret_cast , mặc dù trong thực tế, nó có thể làm điều tương tự. Mặt khác, nếu bạn truyền giữa các loại con trỏ (chẳng hạn như khá phổ biến khi lập chỉ mục trong bộ nhớ thông qua char * chẳng hạn), static_cast sẽ tạo ra lỗi trình biên dịch và dù sao bạn cũng sẽ buộc phải sử dụng reinterpret_cast .
Trong thực tế, tôi sử dụng reinterpret_cast vì nó mô tả rõ hơn về ý định của hoạt động diễn viên. Bạn chắc chắn có thể tạo một trường hợp cho một toán tử khác chỉ định diễn giải lại con trỏ (chỉ đảm bảo trả lại cùng một địa chỉ), nhưng không có một tiêu chuẩn nào trong tiêu chuẩn.
reinterpret_cast
!
Tôi đề nghị sử dụng các diễn viên yếu nhất có thể luôn luôn.
reinterpret_cast
có thể được sử dụng để truyền con trỏ tới float
. Dàn diễn viên càng phá vỡ cấu trúc thì càng cần phải chú ý sử dụng nó.
Trong trường hợp char*
, tôi sẽ sử dụng dàn diễn viên kiểu c, cho đến khi chúng tôi có một số reinterpret_pointer_cast
, vì nó yếu hơn và không có gì khác là đủ.
float f = *reinterpret_cast<const float*>(&p);
float
, đó là sai. Biểu thức void **
chuyển sang const float *
, và sau đó sử dụng một hoạt động bổ nhiệm (KHÔNG phải là diễn viên), để chuyển đổi const float *
thành float
.
Sở thích cá nhân của tôi dựa trên kiến thức mã như thế này:
void* data = something;
MyClass* foo = reinterpret_cast<MyClass*>(data);
foo->bar();
hoặc là
typedef void* hMyClass; //typedef as a handle or reference
hMyClass = something;
const MyClass& foo = static_cast<MyClass&>(*hMyClass);
foo.bar();
Cả hai đều làm như vậy cuối cùng, nhưng static_cast có vẻ phù hợp hơn trong môi trường ứng dụng trung gian, trong khi diễn giải lại có vẻ giống như một cái gì đó bạn thấy trong thư viện IMHO cấp thấp hơn.