Baik static_cast dan reinterpret_cast tampaknya berfungsi dengan baik untuk membuang void * ke jenis pointer lain. Apakah ada alasan bagus untuk lebih menyukai yang satu dari yang lain?
202
Baik static_cast dan reinterpret_cast tampaknya berfungsi dengan baik untuk membuang void * ke jenis pointer lain. Apakah ada alasan bagus untuk lebih menyukai yang satu dari yang lain?
Jawaban:
Gunakan
static_cast
: ini adalah pemeran tersempit yang menggambarkan dengan tepat konversi apa yang dibuat di sini.Ada kesalahpahaman bahwa menggunakan
reinterpret_cast
akan menjadi pertandingan yang lebih baik karena itu berarti "sama sekali mengabaikan keselamatan jenis dan hanya melemparkan dari A ke B".Namun, ini sebenarnya tidak menggambarkan efek dari a
reinterpret_cast
. Sebaliknya,reinterpret_cast
memiliki sejumlah makna, yang kesemuanya berpendapat bahwa "pemetaan yang dilakukan olehreinterpret_cast
didefinisikan-implementasi." [5.2.10.3]Tetapi dalam kasus khusus casting dari
void*
keT*
pemetaan sepenuhnya didefinisikan dengan baik oleh standar; yaitu, untuk menetapkan tipe ke pointer tanpa typeless tanpa mengubah alamatnya.Ini adalah alasan untuk memilih
static_cast
.Selain itu, dan bisa dibilang lebih penting, adalah kenyataan bahwa setiap penggunaan
reinterpret_cast
benar-benar berbahaya karena mengubah apa pun menjadi hal lain benar-benar (untuk petunjuk), sementarastatic_cast
jauh lebih ketat, sehingga memberikan tingkat perlindungan yang lebih baik. Ini sudah menyelamatkan saya dari bug di mana saya tidak sengaja mencoba memaksa satu jenis pointer ke yang lain.sumber
Ini adalah pertanyaan yang sulit. Di satu sisi, Konrad membuat poin yang sangat baik tentang definisi spesifikasi untuk reinterpret_cast , meskipun dalam praktiknya mungkin melakukan hal yang sama. Di sisi lain, jika Anda melakukan casting di antara tipe pointer (seperti yang biasa terjadi saat pengindeksan dalam memori melalui char *, misalnya), static_cast akan menghasilkan kesalahan kompiler dan Anda akan dipaksa untuk menggunakan reinterpret_cast pula.
Dalam praktiknya saya menggunakan reinterpret_cast karena lebih deskriptif tentang maksud operasi pemeran. Anda tentu bisa membuat kasus untuk operator yang berbeda untuk menunjuk penafsiran ulang pointer saja (yang menjamin alamat yang sama dikembalikan), tetapi tidak ada satu pun dalam standar.
sumber
reinterpret_cast
!Saya sarankan menggunakan pemain terlemah yang mungkin selalu.
reinterpret_cast
dapat digunakan untuk melemparkan pointer ke afloat
. Semakin banyak pemecah struktur yang dilemparkan, semakin banyak perhatian yang dibutuhkan.Dalam hal
char*
, saya akan menggunakan pemeran c-style, sampai kita memiliki beberapareinterpret_pointer_cast
, karena itu lebih lemah dan tidak ada lagi yang cukup.sumber
float f = *reinterpret_cast<const float*>(&p);
float
, yang salah. Ekspresi gipsvoid **
untukconst float *
, dan kemudian menggunakan operasi dereference (yang TIDAK gips), untuk mengkonversiconst float *
kefloat
.Preferensi pribadi saya didasarkan pada literasi kode seperti ini:
atau
Mereka berdua melakukan hal yang sama pada akhirnya, tetapi static_cast tampaknya lebih tepat di lingkungan aplikasi menengah, sementara menafsirkan kembali para pemain sepertinya lebih seperti yang Anda lihat di IMHO perpustakaan tingkat rendah.
sumber