g gaya c atau g gaya c ++


21

Jadi, apa yang kamu gunakan?

int anInt = (int)aFloat;

atau

int anInt = static_cast<int>(aFloat);
// and its brethren

Dan, yang lebih penting, mengapa?

Jawaban:


45

Pertama, pahami bahwa garis-garis itu tidak setara .

int* anInt = (int*)aFloat; // is equivalent to

int* anInt = reinterpret_cast<int*>(aFloat); 

Apa yang terjadi di sini adalah bahwa programmer meminta compiler untuk melakukan apa saja untuk membuat para pemain.

Perbedaannya penting karena menggunakan static_cast hanya akan meminta jenis basis yang "aman" untuk dikonversi, di mana reinterpret_cast akan dikonversi ke apa pun, mungkin hanya dengan memetakan tata letak memori yang diinginkan di atas memori objek yang diberikan.

Jadi, karena "filter" tidak sama, menggunakan gips spesifik lebih jelas dan aman daripada menggunakan gips C, jika Anda mengandalkan kompiler (atau runtime impl. Jika Anda menggunakan dynamic_cast) untuk memberi tahu Anda di mana Anda melakukan sesuatu yang salah , dengan menghindari C cast dan reinterepret_cast.

Sekarang ini lebih jelas, ada satu hal lagi: static_cast, reinterpret_cast, const_cast dan dynamic_cast lebih mudah untuk dicari .

Dan poin pamungkas: mereka jelek . Itu diinginkan. Kode yang berpotensi bermasalah, bau kode, "trik" jelas yang mungkin menghasilkan bug, lebih mudah dilacak ketika dikaitkan dengan tampilan yang jelek. Kode yang salah harus jelek .

Itu "dengan desain". Dan itu memungkinkan pengembang untuk mengetahui di mana dia bisa melakukan hal-hal yang lebih baik (dengan benar-benar menghindari gips, jika tidak benar-benar diperlukan) dan di mana itu baik-baik saja tetapi "didokumentasikan" dalam kode dengan "menandainya" sebagai jelek.

Alasan kedua untuk memperkenalkan pemeran gaya baru adalah bahwa pemeran gaya-C sangat sulit dikenali dalam suatu program. Misalnya, Anda tidak dapat mencari gips dengan mudah menggunakan editor atau pengolah kata biasa. Gips gaya C yang hampir tidak terlihat ini sangat disayangkan karena berpotensi merusak. Operasi yang jelek harus memiliki bentuk sintaksis yang jelek. Pengamatan itu adalah bagian dari alasan untuk memilih sintaks untuk pemain gaya baru. Alasan selanjutnya adalah agar gips gaya baru cocok dengan notasi templat, sehingga pemrogram dapat menulis gips mereka sendiri, terutama gips yang diperiksa run-time.

Mungkin, karena static_cast sangat jelek dan relatif sulit untuk diketik, Anda lebih cenderung berpikir dua kali sebelum menggunakannya? Itu akan baik, karena para pemain benar-benar sebagian besar dapat dihindari dalam C ++ modern.

Sumber: Bjarne Stroustrup (pencipta C ++)


2
Saya akan mengundurkan diri jika saya memiliki beberapa poin lagi, tetapi sayangnya saya tidak bisa. Para pemeran c-style TIDAK setara dengan reinterpret_cast. Pertimbangkan reinterpret_cast<int>(double);. Sangat mungkin untuk melemparkan double ke int dengan cast c-style, tetapi tidak mungkin untuk melakukannya dengan reinterpret_cast. Saya melihat Timbo sudah menunjukkan ini kepada Anda, dan Anda mengatakan Anda akan memperbaikinya, tetapi empat tahun kemudian tetap salah. Saya masih akan menurunkan suara Anda jika itu sudah diperbaiki, karena ada alasan yang sah untuk menggunakan gips. Inilah jawaban yang lebih baik: stackoverflow.com/a/332086/3878168
Yay295

36

C ++ cast lebih terbatas (jadi ekspresikan maksud Anda lebih baik dan buat review kode lebih mudah, dll.). Mereka juga jauh lebih mudah untuk dicari, jika perlu.


10
... dan mereka lebih cenderung melakukan apa yang Anda inginkan. ;-)
Macke

7
Dan mereka jauh lebih banyak untuk diketik, memberi Anda satu alasan lagi untuk hanya mendapatkan tipe yang benar tanpa gips yang dibutuhkan.
Michael Kohne

7
Dan mereka jelek sebagai fitur, memperjelas di mana dalam kode mungkin ada poin perbaikan atau kasus khusus yang mungkin memerlukan dokumentasi. - sunting: wow Saya baru tahu saya juga menjawab pertanyaan ini! XD
Klaim

Sekarang mengapa saya ingin mencari mereka?
Deduplicator

@Deduplicator Ada banyak alasan Anda mungkin ingin tahu di mana para pemain sedang terjadi dalam basis kode. Misalnya ketika berburu bug yang dapat dikaitkan dengan casting (khususnya ketika melakukan pengembangan lintas platform).
Klaim

13

Opsi C: pemeran "C ++ - style", karena tidak dapat dibedakan dari konstruksi:

int anInt = int(aFloat);

atau bahkan:

int anInt(aFloat);

Selain itu, selain dari kasus-kasus sepele dengan primitif, yang dipahami dengan baik, saya lebih suka menggunakan x_cast <> di atas gips C-style. Ada tiga alasan mengapa:

  • Mereka lebih sempit mendefinisikan operasi yang coba dilakukan oleh programmer.

  • Mereka dapat melakukan tindakan yang tidak bisa dilakukan oleh gaya-C (terutama dalam kasus dynamic_cast <>, yang dapat melakukan lintas silang di seluruh cabang rantai multi-warisan).

  • Mereka jelek . Mereka dengan keras menyatakan bahwa programmer bekerja melawan sistem tipe. Dalam hal ini, itu hal yang baik .


7

Jika menulis kode dalam C gunakan cast C. Jika menulis dalam C ++ gunakan pemeran C ++.

Sementara sebagian besar casting merusak keselamatan tipe yang tepat, yang C ++ lebih ketat, dan karena itu Anda sedikit kurang tipe-tidak aman daripada Anda akan dengan pemain C.

Saya dapat mentolerir seseorang menggunakan (T *) NULL meskipun untuk memaksa kelebihan ...


7

Saya punya beberapa aturan tentang C / C ++ - style cast:

  1. Dis-apply const harus selalu menggunakan a const_cast. Untuk alasan yang jelas. Sayangnya, aturan saya tentang dis-menerapkan sebuah konst menyebabkan keyboard untuk meraih dan mematahkan jari programmer tidak disetujui.
  2. Shenanigans gaya manipulasi bit mana pun yang harus digunakan programmer saat turun ke logam harus digunakan reinterpret_cast. Ini benar-benar jenis pemeran yang tidak dimiliki C: pura-pura bilangan bulat ini sebenarnya adalah bit pelampung. Ini menghindari ketidaknyamanan seperti (int)(*(int*)(&floatVar)).
  3. Jika Anda mengetik kata-kata " dynamic_cast", hentikan dan evaluasi ulang hierarki dan desain kelas polimorfik Anda. Lanjutkan mengevaluasi kembali desain hierarki kelas Anda hingga Anda dapat menghapus kata-kata itu.
  4. Jangan repot-repot static_cast.

Alasan di balik # 4 hanya karena itu tidak masalah. Keadaan yang tidak sesuai dengan aturan lain jelas atau benar-benar tingkat rendah. Konversi yang dipahami dengan baik dari tipe sederhana seperti int-to-float seharusnya tidak memerlukan sintaks khusus. Dan jika Anda berada di dalam perut yang buruk, sesuatu yang buruk, yah, Anda berada di perut yang dalam, sesuatu yang buruk. Tidak perlu untuk menarik perhatian pada kenyataan bahwa "di sini ada naga," karena gigi, cakar, dan api sudah cukup memberikannya.


1
dynamic_castadalah alat yang sangat valid. Akan sangat berguna, saya akui, tetapi itu jauh dari Setan hal-hal seperti variabel global. Namun, terutama, saya menurunkan Anda karena Anda tidak menjawab pertanyaan , yang tentang penggunaan atau tidak dari pemeran gaya-C.
DeadMG

2
@DeadMG: Saya memang berbicara tentang gips C-style. Seluruh paragraf terakhir membenarkan pemeran gaya-C yang mendukung static_cast.
Nicol Bolas

"Sayangnya, aturan saya tentang tidak menerapkan konstitusi menyebabkan keyboard menjangkau dan mematahkan jari programmer tidak disetujui." Secara teknis sebenarnya legal bagi kompiler untuk mewujudkannya. Sebagaimana sah bagi kompiler untuk membuat setan terbang keluar dari hidung Anda .
Pharap


3

Itu benar-benar tergantung pada bahasa mana saya bekerja, karena Anda tahu apa yang mereka katakan: Di Roma berbicara bahasa Romawi. Jadi jika saya pemrograman di C, saya mencoba menggunakan fitur C ke max, tetapi jika saya pemrograman di C ++ saya lanjutkan dan menggunakan fitur C ++ ke max, bahkan jika beberapa orang tidak suka pendekatan itu karena mereka mengatakan itu membuat kode "kurang portabel", saya mengatakan bahwa saya tidak peduli, saya di C ++ dan pemrograman di C ++, dan saya memerlukan kompiler yang sepenuhnya kompatibel dengan C ++ untuk mengkompilasi kode, kalau tidak saya akan bekerja dengan sesuatu yang berbeda di tempat pertama.


Itu tidak benar-benar bekerja mencoba menggunakan C ++ - gaya gips di C ;-)
Steve314

3

static_cast dll diciptakan karena masalah dengan cast gaya C ketika digunakan dalam template. Jika Anda menulis templat, atau jika kode Anda nanti dapat dikonversi menjadi templat, sebaiknya gunakan cetakan gaya C ++. Alasannya adalah karena gaya C ++-cast memberikan maksud mengekspresikan yang lebih baik, sehingga mereka akan memberikan hasil yang diharapkan dalam kasus-kasus di mana cast-style C akan melakukan hal yang salah (diberikan tipe tertentu sebagai parameter templat).

Selain itu, saya katakan menggunakan pemeran gaya C ++ jika Anda memiliki masalah khusus yang membutuhkannya - dynamic_cast adalah yang paling umum, tetapi bahkan itu mungkin bukan hal yang biasa.

Ada hal lain, dan pemeran gaya C mungkin sedikit kurang berantakan dan membantu keterbacaan, atau mungkin tidak tergantung pada seberapa akrab pembaca dengan gaya pemeran saat ini. Itu tidak terlalu penting dalam pandangan saya, kebanyakan hal preferensi pribadi, meskipun jangan heran jika beberapa orang tidak menyukai gaya C.

Catatan akhir - jika Anda membutuhkan banyak pemain sehingga ini adalah masalah besar, Anda mungkin melakukan sesuatu yang salah. Ada pengecualian untuk itu dalam beberapa kasus, tetapi sebagian besar kode level tinggi seharusnya tidak membutuhkan banyak (jika ada) gips.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.