Dalam C / C ++, haruskah saya menggunakan 'const' dalam parameter dan variabel lokal bila memungkinkan?

13

Pertanyaan ini diinspirasi oleh pertanyaan tentang finaljava .

Dalam C / C ++, haruskah saya menggunakan constjika memungkinkan?

Saya tahu sudah ada pertanyaan terkait tentang penggunaan constparameter . Sayangnya pertanyaan itu dan jawabannya tidak sepenuhnya menjawab pertanyaan saya, karena ini hanya tentang parameter fungsi, tetapi saya juga ingin tahu tentang kasus-kasus lain (misalnya: variabel lokal).

Juga, hampir semua jawaban untuk pertanyaan itu mengatakan kita harus menggunakan constkarena berisi informasi yang berguna tentang aksesibilitas variabel. Tapi ini tampaknya bertentangan dengan jawaban tentang penggunaan final di Jawa yang menyatakan finalmungkin berlebihan jika tidak mengandung informasi tambahan dan karenanya harus dihilangkan agar kode tetap pendek dan bersih.

Jadi, haruskah saya menggunakan constjika memungkinkan? Jika demikian, mengapa saran untuk constdi C ++ berbeda dengan saran untuk finaldi Jawa?

ocomfd
sumber

Jawaban:

18

Pertama-tama, karena Anda mereferensikan Java final, itu adalah binatang yang sama sekali berbeda dari const. Final berarti referensi tidak dapat berubah, tetapi tidak mengatakan apa pun tentang kemampuan berubah-ubah. Const melangkah lebih jauh dengan mengatakan "referensi const tidak dapat bermutasi" yang merupakan jaminan yang jauh lebih kuat. Untuk melakukan ini di Jawa, keadaan internal harus final dan ditentukan pada waktu konstruksi. Const jauh lebih mudah digunakan, dan objek yang ada dapat "dipromosikan" menjadi referensi const.

Ya, Anda harus menggunakan const jika memungkinkan. Itu membuat kontrak bahwa kode Anda tidak akan mengubah sesuatu. Ingat, variabel non-const dapat diteruskan ke fungsi yang menerima parameter const. Anda selalu dapat menambahkan const, tetapi tidak menghilangkannya (bukan tanpa cast const yang merupakan ide yang sangat buruk).

Benar-benar kadang-kadang membosankan, tetapi membantu menjamin keabadian. Ini sangat penting dalam kode multi-utas tempat utas berbagi objek. Itu membuat tugas-tugas tertentu lebih efisien: daripada menyalin negara, hanya menggunakan kembali objek abadi yang sama. Perpustakaan mungkin menerima parameter const untuk memberikan jaminan kepada programmer bahwa tidak, objek Anda tidak akan berubah dengan cara yang tidak dapat diprediksi di lubang hitam yang merupakan nyali perpustakaan.


sumber
1
Pilih karena Anda menjelaskannya finaldan consttidak memiliki jaminan yang sama.
Bill Door
2
Keteguhan adalah tentang kemampuan menulis, bukan tentang kemampuan berubah-ubah.
Basilevs
@ Basilevs apa yang terjadi jika Anda menulis ke objek? Itu bermutasi. Bagaimana Anda bermutasi objek? Menulis untuk itu.
4
Apa yang terjadi jika Anda menulis ke referensi const? Kesalahan waktu kompilasi. Apa yang terjadi jika Anda menulis ke objek yang direferensikan di suatu tempat oleh referensi const melalui referensi non-const lainnya? Itu bermutasi. Objek yang tidak dapat diubah tidak dapat bermutasi, oleh karena itu referensi referensi tidak selalu merujuk objek yang tidak dapat diubah.
Basilev
@ Basilevs pengamatan Anda hanya berlaku dengan const ref. Jika suatu objek itu sendiri dinyatakan const (bukan hanya referensi) maka itu lebih atau kurang abadi (kecuali seseorang dengan jahat membuang constness).
Matthew James Briggs
4

Secara pribadi, constsaya butuh sedikit waktu untuk menulis, dan sangat sedikit waktu untuk membaca, biasanya jauh lebih sedikit daripada yang diperlukan untuk memeriksa apakah ada kode yang mengubah variabel, dan itu benar-benar mencegah saya dari menulis bug (ada yang pernah menambah iterator akhirnya secara kebetulan? Dll)

Saya juga menemukan bahwa menjadi ketat tentang penggunaan const membimbing saya menuju kode yang lebih baik dengan cara lain, seperti membuat fungsi pembantu untuk melakukan inisialisasi non-sepele.

Bwmat
sumber
4

Saya tidak akan setuju dengan poster lain dan merekomendasikan Anda untuk tidak menggunakan tingkat constatas pada variabel dan parameter lokal. (Referensi dan pointer ke const, yaitu const T&berbeda, dan Anda harus menggunakannya untuk kebenaran setiap saat jika sesuai.)

Keuntungan dari tingkat atas constadalah:

  • Jelaskan bahwa variabel lokal tidak dimaksudkan untuk dimutasi.
  • Memberikan kesalahan kompiler jika Anda secara tidak sengaja berusaha untuk memutasinya.

Kerugiannya adalah:

  • Kekacauan visual.
  • Tidak dapat digunakan pada variabel "pseudo-const", yaitu variabel yang diinisialisasi dalam beberapa cara lebih rumit daripada konstruksi langsung, tetapi tidak dimodifikasi setelah, misalnya menggunakan getline:

    std::string line; // cannot be const
    std::getline(std::cin, line);
    // line should be const from here on out
  • Mencegah pengaktifan keluar pada panggilan fungsi dan kembali:

    std::string f1();
    std::string f2(std::string s);
    std::string f3() {
      const std::string s = f1(); // s is not meant to be modified
      // but I still want the move optimization here:
      const std::string result = f2(std::move(s)); // this doesn't move
      // and I want the compiler to move out here:
      return result; // this will probably RVO, but if not, the move
                     // constructor will not be used due to the const
    }

Saya telah bekerja pada basis kode di mana lokal constbanyak digunakan, dan saya merasa itu tidak membantu sama sekali, namun itu mengisi kode dengan pesimisasi halus seperti di atas. Saya pribadi lebih suka mengadopsi kebijakan umum memodifikasi variabel sesering mungkin, dan membuat fungsi cukup kecil sehingga penggunaan variabel jelas, dan bahkan jika dimodifikasi, kompleksitas fungsi cukup rendah untuk membuatnya menjadi non -isu.

Sebastian Redl
sumber
2
Poin Anda tentang pindah-dari menunjukkan di mana Anda tidak menggunakan lokal secara konstan, karena Anda (berniat) memodifikasinya dengan bergerak
Caleth
1
@ Caleth Tidak, itu intinya. Saya tidak bermaksud memodifikasinya. Saya hanya ingin memberikan nilai, atau mengembalikannya, dan saya ingin ini menjadi efisien. Secara konseptual, modifikasi hanyalah optimasi, yang tidak dimaksudkan untuk diamati (karena variabel tidak digunakan setelahnya). Praktis, ya, ada modifikasi, karena C ++ tidak memiliki gerakan destruktif sejati (seperti yang dimiliki Rust). Itulah mengapa saya tidak ingin constpada penduduk lokal: karena itu mencegah modifikasi teknis, bukan hanya modifikasi konseptual.
Sebastian Redl
2
Anda tidak ingin mengubah nilai , tetapi Anda ingin memodifikasi variabel . Anda bisa menggunakan const & sebagai gantinya, dan memodifikasi keduanya
Caleth
2

Kata constkunci harus digunakan untuk variabel lokal, seperti halnya parameter. Ini berguna karena:

  • Lebih mudah membaca kode. Ketika seseorang membaca deklarasi variabel, dia tahu itu tidak akan berubah. Satu hal lagi yang perlu dikhawatirkan saat membaca kode Anda.
  • Mencegah Anda memodifikasi variabel secara tidak sengaja
  • Tidak ada penalti runtime, semuanya diperiksa secara statis. Ini seperti makan siang gratis, consthanya perlu satu detik untuk menulis, jadi itu bukan masalah besar.
  • Itu selalu ide yang baik untuk membuat variabel / parameter Anda di aplikasi multi-threaded Anda. Bahkan aplikasi Anda tidak multi-threaded, itu masih kebiasaan yang baik.
  • Anda memberi kesempatan bagi kompiler C ++ Anda untuk mengoptimalkan kode Anda.

Perhatikan bahwa tidak ada jawaban benar / salah di sini. Di tautan Anda, penjawab yang paling banyak berselisih pendapat finaltidak boleh digunakan secara lokal. Namun, penjawab berikutnya sangat merekomendasikannya.

Jika fungsi Anda sederhana dan sepele , Anda tidak boleh menambahkan constkarena semua orang mengerti maksud Anda. Namun, jika logika dalam fungsi Anda non-sepele, Anda harus menggunakan kata kunci. Ingat, ada sedikit yang hilang.

Halo Dunia
sumber