Bagaimana Anda menjadi orang yang insaf yang bertobat? [Tutup]

25

Setelah 15 tahun C ++, saya masih belum belajar untuk suka menggunakan const. Saya mengerti ini digunakan, tetapi saya tidak pernah benar-benar berada dalam situasi di mana menjadi const benar akan menghindari masalah yang saya hadapi.

Jadi, bagaimana Anda bisa mencintai manfaat consts?

grok
sumber
3
Saya pikir kebenaran const lebih dari yang benar daripada alat untuk memecahkan masalah seperti jika dipotong atau sizeof operator.
legends2k
9
"Alasan mengapa const bekerja di C ++ adalah karena kamu bisa membuangnya. Jika kamu tidak bisa membuangnya, maka duniamu akan payah." - Anders Hejlsberg
Mason Wheeler
1
const juga merupakan pengubah tipe C dan telah sejak standar ANSI C pertama.
Huperniketes
Karena dimanja oleh Java / C #, saya adalah tipe paranoid yang suka meninggalkan menegaskan setiap kesempatan yang saya dapatkan. Apa yang bisa salah akan salah. Jika ada waktu kompilasi atau bantuan run-time, hitung saya! Saya menjadi mualaf segera setelah saya mendengarnya 3-4 kali, dan mengikuti sebagian tautan ini (cukup untuk melihat sintaksnya, saya tidak perlu membaca tentang alasannya): chance.com/Cpp/const.html Hanya karena sesuatu belum meledak di wajah saya ... butuh sedikit usaha untuk menjadi benar, dan itu tidak sakit. Lihatlah pemikiran Joel: joelonsoftware.com/articles/Wrong.html
Job

Jawaban:

28

Yah saya tidak yakin sampai saya mencoba merangkul filosofi.

Pertama-tama saya mulai dengan mengajukan constargumen yang hanya bisa dibaca oleh anggota kelas saya yang paling mendasar dan argumen fungsi anggota.

Dari sana, saya tidak bisa mengkompilasi lagi. Kemudian saya tekun dalam mencari kode menggunakan kelas-kelas dasar, melihat apakah constpenambahan sebelumnya benar-benar sah dibandingkan dengan penggunaan yang saya buat dari mereka. Itu membantu saya memperbaiki beberapa bug di jalan ketika saya menambahkan keteguhan pada bagian lain dari kode.

Ini menular. Sebagian besar kode mendapatkan lebih banyak keteguhan dan saya menemukan lebih mudah untuk men-debug itu karena membuat Anda yakin bahwa kompiler akan menghentikan Anda jika Anda mulai memodifikasi sesuatu yang tidak seharusnya.

Setelah saya menjalankan aplikasi lagi, itu lebih cepat (harus mengubah beberapa algoritma yang saya temukan tidak cocok untuk pekerjaan itu), dengan bug yang jauh lebih sedikit dan lebih mudah untuk dipahami ketika membaca kode.

Saya yakin.

Sekarang, saya pikir itu lebih baik ketika Anda menggunakan banyak pernyataan selain dari constness karena itu membuat Anda merasa percaya diri ketika Anda harus menulis kode baru atau memodifikasi kode saat ini. Anda tahu kompiler akan menghentikan Anda jika perlu. Ini memungkinkan Anda lupa tentang harus memeriksa segala sesuatu yang tidak boleh Anda modifikasi dan kemudian Anda memiliki lebih banyak waktu untuk berpikir lebih spesifik untuk bisnis, atau pemikiran arsitektur.

Klaim
sumber
8
1 untuk menular yang intinya berarti Anda harus menjadi orang yang mengonversi atau sepenuhnya menghindarinya.
Martin Wickman
Anda juga tidak perlu bergantung pada lib yang tidak melakukan kebenaran konst. Pendekatan Anda tidak berfungsi ketika itu berarti Anda tidak dapat memanggil salah satu fungsi gui karena itu bukan konstanta - atau Anda perlu membuangnya di setiap panggilan gui.
Martin Beckett
4
+1 untuk "merasa lebih mudah untuk di-debug", saya menggunakan constbahkan untuk variabel lokal yang saya tahu saya tidak perlu berubah, dengan cara ini ketika membaca kode saya dapat membaca lebih dari satu ifatau lebih foratau lebih: variabel saya adalah konstan, saya tahu itu tidak akan berubah! Saya tidak peduli tentang optimisasi, tetapi saya memiliki otak yang terbatas, dan beberapa tingkat indentasi + koreksi benar sangat membantu!
Matthieu M.
@MatthieuM .: Pernah mempertimbangkan beralih ke Haskell? ;-)
Giorgio
@Iorgio: Saya sudah menjelajahinya, bahkan membeli "Real World Haskell". Sejujurnya saya tidak senang dengan kemalasan secara default dan banyak operator samar yang bermunculan.
Matthieu M.
15

Saya tidak pernah menjadi pendukung pemrograman berorientasi objek, dan jika ada sesuatu yang saya kembangkan semakin sedikit sehingga semakin banyak yang saya pelajari tentang pemrograman secara umum. Seperti yang saya sudah mempelajari paradigma pemrograman yang berbeda, aku menyadari bahwa kekekalan adalah salah satu yang konsep pusat desain program, yang mempengaruhi perangkat lunak yang ditulis sesuai dengan setiap filsafat. Ini sangat penting dalam pemrograman fungsional, dengan implikasi dalam optimasi dan konkurensi di atas jaminan keselamatan sederhana.

Pada dasarnya, semua yang bisa berubah mungkin harus , kecuali Anda punya alasan yang bagus untuk keadaan yang bisa berubah. Dalam pengalaman saya, menulis program dalam bahasa apa pun untuk mencapai tujuan ini mengarah pada kode yang lebih aman dan lebih baik . Anda tidak akan rugi dengan menggunakan constmana yang berlaku — keabadian gratis!

(Kebetulan, saya bermain-main dengan gagasan membuat garpu GCC untuk dialek C ++ di mana semua jenis constkecuali memenuhi syarat secara eksplisit mutable. Jika ada dukungan untuk hal seperti itu, saya benar-benar akan berkomitmen untuk mempertahankan dan menggunakannya.)


Dari sudut pandang OO, immutability memberlakukan enkapsulasi dengan mencegah akses tulis tidak terbatas. Ini mengurangi kopling antar kelas karena objek yang tidak dapat diubah harus sepenuhnya mengelola negara mereka sendiri dan dengan demikian berperilaku seperti nilai-nilai biasa. Kebenaran Konst secara signifikan memudahkan proses pembuktian kebenaran program, terutama dalam konteks pemrograman bersamaan. Dengan referensi C ++ dan semantik referensi nilai C ++ 0x, Anda dapat menggunakan objek yang tidak dapat diubah tanpa khawatir tentang biaya penyalinannya di semua tempat. Lebih lanjut, kompiler dapat bekerja dengan sihir optimasi yang sangat luar biasa jika Anda bekerja dengan sebagian besar objek yang tidak dapat diubah.

Saya tahu ini menyebalkan untuk mengetik di constmana-mana, tetapi Anda dengan cepat terbiasa dengannya, dan manfaatnya menjadi jelas seiring waktu dalam hal keandalan dan pemeliharaan. Saya bukan penulis yang brilian, dan tampaknya menjadi tugas yang terbukti sulit untuk membuat kasus untuk itu, tapi saya tahu bahwa kebenaran const telah sangat membantu saya sebagai pengembang ketika merancang dan mengimplementasikan program, dan saya pikir pengalaman adalah guru terbaik dalam hal ini.

Jon Purdy
sumber
2
Anda pada dasarnya hanya mengatakan bahwa kebenaran const adalah Good Thing. Anda mengatakan bahwa "mengarah ke kode yang lebih aman dan lebih baik". Bisakah Anda mengatakan mengapa?
David Reis
Saya benar-benar di kamp imutabilitas, bahasa favorit saya adalah Erlang. Tapi saya berpendapat bahwa immutability via const di C ++ tidak benar-benar gratis. Ada kelemahan seperti kode yang kurang mudah dibaca, versi const dan non const dari metode yang sama, atau membuang const karena "tidak ada pilihan lain".
grok
1
Saya sarankan tidak hanya menggunakan mutable, karena memiliki arti yang jelas dalam hal kebenaran const. Ini berarti bahwa objek data ini dapat berubah dengan cara yang tidak mempengaruhi perilaku objek, dan memungkinkan hal-hal seperti caching jawaban. Buat kata kunci lain.
David Thornley
2
@ David Thornley: Demi konsistensi, mutableadalah pilihan yang logis. void alter(mutable Point&)masuk akal, seperti halnya mutable int foountuk variabel lokal, dan tak satu pun dari konflik ini dengan bahasa yang ada atau penggunaan yang ada mutable. Juga, Object mutable* mutableterlihat cukup menakutkan untuk menjadi peringatan tentang apakah itu perlu atau benar.
Jon Purdy
Jika Anda pernah melakukan garpu, pertimbangkan untuk menggunakan dentang - seharusnya tidak terlalu menyakitkan.
gf
6

Keuntungan dari benar const adalah bahwa ia memaksakan disiplin pada program, dan membuatnya lebih mudah untuk alasan tentang bagian-bagian dari program.

Disiplinnya adalah Anda perlu tahu di mana sesuatu bisa berubah. Keuntungan yang sesuai adalah bahwa lebih mudah untuk melihat apa yang dilakukan sepotong kode ketika Anda dapat mengetahui apa yang mungkin mengubah keadaan.

David Thornley
sumber
1
"Program harus ditulis untuk dibaca orang, dan hanya secara kebetulan untuk dijalankan mesin." - Abelson & Sussman, SICP
Brandon DuRette
4

Menjadi benar const menekankan kebenaran dari desain yang saya memperlakukan dekat dengan masalah serupa yang tidak menggunakan operator cor; jadi tidak menggunakan gips dan menjadi benar, penggunaan minimal bisa berubah - semua ini adalah petunjuk untuk mengukur seberapa baik desain tetapi bukan alat yang sebenarnya untuk memecahkan masalah secara keseluruhan di tangan.

PS: Saya benar-benar yakin constbegitu saya mengerti benar menggunakannya;)

legends2k
sumber
2

Saya melihat dua alasan utama untuk menulis kode const-correct. Salah satunya adalah bahwa kompiler adalah teman Anda, dan dengan menggunakan const Anda membiarkannya memperingatkan Anda tentang bug potensial. Alasan kedua adalah bahwa const-correctness membuat kode lebih mudah dibaca. Misalnya, Anda selalu tahu argumen fungsi mana yang merupakan input dan mana yang merupakan output. Anda juga tahu fungsi anggota mana yang memodifikasi objek dan mana yang tidak. Anda mengetahui hal-hal ini secara instan tanpa harus membaca kode. Ini, tentu saja, mengasumsikan penggunaan yang sangat bijaksana const_cast.

Dima
sumber
2

Saya bertobat segera setelah saya tahu itu mungkin. Masuk akal bagi saya dari sudut pandang 'gaya pemrograman yang bagus'. Ada berbagai alasan mengapa menjadi praktik yang benar adalah benar:

  • Keterbacaan dan pemahaman. Jika saya membaca kode orang lain dan suatu fungsi mengambil referensi const sebagai parameter, saya tahu bahwa parameter hanya dimaksudkan untuk digunakan sebagai variabel read-only. Ini adalah kemenangan besar terutama jika kode lingkungan multi-threaded.
  • Kompiler dapat menggunakan kualifikasi const untuk membantu operasinya.
  • Katakanlah saya memiliki objek kelas A dalam situasi di mana saya tidak ingin itu berubah. Maka satu-satunya fungsi anggota yang dapat dipanggil untuk objek itu adalah fungsi yang konst.
sashang
sumber
2

Untuk merangkum dua poin yang telah dibahas dalam jawaban lain, dan tambahkan yang baru:

  • constmendokumentasikan kode tersebut kepada pengguna API Anda. Ini membentuk kontrak antara fungsi dan pemanggilnya, bahwa fungsi tidak akan mengubah parameternya. (Harap dicatat bahwa const_casttidak mengaktifkan fungsi untuk mengubah parameternya, itu memungkinkan melewati parameter itu ke fungsi lain yang tidak mengubah parameter mereka tetapi lupa constpenjelasannya.) Hal ini juga berguna di dalam fungsi / loop / etc karena membantu banyak memahami cara yang sama dengan invarian loop.

  • constmendokumentasikan maksud Anda ke kompiler. Menemukan kesalahan pada waktu kompilasi selalu lebih baik daripada menunggu potongan kode itu dijalankan.

  • constdiperlukan untuk jenis polimorfisme yang aman. Pointer (dalam semua bentuk mereka, bukan hanya pointer mentah) hanya kovarian jika mereka const(Catatan: tidak sama dengan "pointer ke const"). Kovarian memerlukan antarmuka read-only, dan contravariance memerlukan antarmuka tulis-saja.

Yang kedua ini saya pelajari dulu. Saya mulai dengan consthanya pada parameter penunjuk dan referensi, hingga saya mulai melihat manfaat dari menangkap kesalahan sebelumnya, dan mulai menggunakannya pada penduduk setempat, dll.

Kemudian saya belajar bahwa sebagian besar #defines dapat diganti (dalam C ++) oleh konstanta global, dengan manfaat tambahan dari keamanan tipe. Jadi saya menggunakannya di sana juga.

Akhirnya saya mengambil kelas tentang sistem tipe dan kalkulus lambda, dan belajar bahwa constdan non- consttipe pada dasarnya berbeda (karena mereka mendukung operasi yang berbeda), dan sejak itu saya bahkan tidak pernah mempertimbangkan untuk menulis kode C ++ tanpa menggunakan banyak const.

Ben Voigt
sumber
1

Inilah 5 sen saya dari apa yang belum pernah saya lihat orang lain sebutkan. Ketika melewati variabel Anda tidak ingin melewati nilai, kecuali Anda benar-benar perlu, untuk menghindari konstruksi dan perusakan dan salinan tambahan. Jadi kecuali Anda benar-benar harus melewati nilai, menggunakan referensi di mana-mana, bahkan jika Anda tidak bermaksud mengubah nilai yang diteruskan adalah peningkatan kinerja yang signifikan. Untuk alasan ini, ketika Anda memiliki fungsi yang mengambil referensi dari semua argumennya, Anda harus memberi tahu pemanggil fungsi yang tidak akan dimodifikasi.

Ini prinsip yang sama, tapi saya hanya ingin menambahkan alasan praktis menggunakan const.

Nikiforos Rotas
sumber