Apakah keterbacaan merupakan alasan yang valid untuk tidak menggunakan parameter const dalam (referensi)?

24

Saat menulis beberapa fungsi, saya menemukan kata kunci const dalam parameter seperti ini:

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
}

sering menyebabkan pemisahan baris menjadi 2 baris dalam IDE atau vim, jadi saya ingin menghapus semua kata kunci const dalam parameter:

void MyClass::myFunction(MyObject& obj,string& s1,string& s2,string& s3){
} 

apakah itu alasan yang sah untuk tidak menggunakan const? Apakah dapat dipertahankan untuk menjaga objek parameter tidak berubah secara manual?

ggrr
sumber
110
"Hai, saya ingin secara fungsional mengubah program saya" untuk membuatnya lebih mudah dibaca adalah alasan buruk yang buruk.
Pieter B
37
Program ini tidak menjadi lebih mudah dibaca - Sekali Anda melihat sesuatu diserahkan karena constAnda memiliki petunjuk kuat bahwa Anda tidak perlu repot-repot bagaimana itu dapat diubah dalam fungsi.
tofro
43
Cara yang lebih baik untuk meningkatkan keterbacaan adalah dengan mengurangi jumlah argumen.
5gon12eder
15
'const' bisa dibilang meningkatkan keterbacaan. Pernyataan ini menjelaskan bahwa obj mungkin tidak berubah!
Charles
14
Apa yang akan membantu keterbacaan adalah menambahkan spasi setelah setiap koma.
sam hocevar

Jawaban:

182

Keterbacaan adalah alasan yang valid untuk belajar menggunakan spasi putih:

void MyClass::myFunction(
        const MyObject& obj,
        const string& s1,
        const string& s2,
        const string& s3
) {
    return;
}

Terletak di sana parameter tidak akan bingung dengan tubuh fungsi. Dengan menempatkan mereka pada baris yang berbeda, Anda tidak perlu memposisikan ulang ketika Anda mengubah nama myFunctionmenjadi sesuatu yang lebih deskriptif. Tidak mengubah posisi parameter ketika mereka belum berubah adalah sesuatu yang akan dihargai oleh pengguna alat kontrol sumber.

constberarti sesuatu. Jangan membuangnya hanya karena Anda kehabisan ruang dan ide. Keterbacaan adalah raja tetapi melanggar hal-hal dalam namanya hanya menyerah.

candied_orange
sumber
6
"Anda tidak perlu memposisikan ulang ketika Anda mengubah nama fungsi saya" - meskipun dalam kasus ini sepertinya mereka diposisikan kira-kira sejajar dengan pembukaan (, dan jika itu yang terjadi maka Anda mungkin harus memposisikan ulang mereka jika panjang nama fungsi kelas + berubah lebih dari sekitar 4 karakter. Jadi, jika Anda ingin tidak harus melakukan itu, tambahkan sejumlah tingkat lekukan, bukan angka yang tergantung pada panjang nama fungsi. Saya akan merekomendasikan 1 level, jawaban ini menggunakan 6, tetapi setiap nomor tetap mencapai tujuan yang dinyatakan :-)
Steve Jessop
6
@CandiedOrange Saya terkejut Anda tidak menggunakan "form 6" dalam jawaban ini ... itu jelas kurang jelek!
svidgen
6
Formulir 6 untuk kemenangan. Satu tabspace untuk satu tingkat indentasi. Sederhana dan efektif. Masalah terpecahkan :)
Lightness Races dengan Monica
2
Ok ok bentuk 6 itu. Ini adalah varian yang disebutkan JeffGrigg pada c2.
candied_orange
4
@ random832 Saya pikir kami dengan tegas berada di wilayah gudang sepeda sekarang. Inilah cara yang tepat untuk mengatasinya: cari contoh kode di dasar Anda, bacalah panduan gaya toko Anda, tanyakan pengembang di toko Anda, dan jika tidak ada yang menghasilkan jawaban otoritatif gunakan ini. Selesaikan perselisihan yang bisa berjalan baik dengan seperempat. Setelah kuartal berbicara konsisten!
candied_orange
52

Sebenarnya, masalah keterbacaan jelas mengarah ke arah lain. Pertama, Anda dapat dengan mudah menyelesaikan run-on line Anda dengan menggunakan spasi . Tetapi menghapus consttidak hanya membuat garis lebih pendek, itu benar-benar mengubah arti dari program.

Herb Sutter merujuk constpada referensi constsebagai yang paling pentingconst karena referensi untuk constdapat mengikat untuk sementara dan memperpanjang masa pakainya. Referensi nilai non const-tidak bisa, Anda memerlukan variabel terpisah.

void foo_const(std::string const& );
void foo_nc(std::string& );

std::string some_getter();

foo_const(some_getter());      // OK
foo_const("Hello there"); // OK

foo_nc(some_getter()); // error
foo_nc("Nope");   // error

std::string x = some_getter(); // have to do this
foo_nc(x);                     // ok
std::string msg = "Really??";  // and this
foo_nc(msg);                   // ok

Apa artinya ini bagi kegunaan adalah bahwa Anda harus memperkenalkan semua variabel sementara ini hanya untuk dapat memanggil fungsi Anda. Itu tidak bagus untuk dibaca, karena variabel-variabel ini tidak ada artinya dan hanya ada karena tanda tangan Anda salah.

Barry
sumber
6
Paragraf kedua Anda membuat saya sakit kepala ketika mencoba mencari tahu apakah constitu merujuk constke yang lain constdan apa constyang memang paling pentingconst
Mindwin
3
@Mindwin Saya pikir ironinya adalah paragraf kedua saya jelas dan tidak ambigu, dan saya tidak tahu apa yang Anda bicarakan.
Barry
2
@ Larry Ini memang tidak ambigu, tapi saya butuh beberapa bacaan paragraf untuk mencoba mencari tahu apa artinya. Saya pikir beberapa masalah adalah dapat diurai "Herb Sutter merujuk ke const (mengacu pada const) sebagai const yang paling penting ..." atau "Herb Sutter merujuk ke const dalam (referensi ke const) sebagai yang paling const penting ... "Saya percaya yang terakhir adalah satu-satunya pengelompokan kata-kata yang valid, tetapi butuh sedikit untuk memprosesnya. Mungkin ada cara untuk menggunakan tanda kutip untuk menghapus ambiguitas?
Cort Ammon - Reinstate Monica
1
Saya pikir beberapa senyawa ditulis dgn tanda penghubung akan membersihkan ini.
shawnt00
2
atau secara khusus menggunakan const&daripada merujuk constsebagai kata benda (-fase) di sana
Caleth
21

Jawaban sederhana adalah "tidak".

Jawaban panjangnya adalah bahwa constkata kunci adalah bagian dari kontrak yang ditawarkan fungsi; itu memberitahu Anda bahwa argumen tidak akan diubah. Saat Anda menghapus constjaminan itu keluar dari jendela. Ingatlah bahwa Anda tidak dapat secara wajar menjaga ketegaran (atau properti lainnya) dari sesuatu yang menggunakan dokumentasi, konvensi, atau pedoman - jika ketegaran tidak ditegakkan oleh kompiler, seseorang akan berpikir bahwa mereka dapat membuat pekerjaan mereka lebih mudah jika mereka mengutak-atik parameter "hanya sedikit". Mempertimbangkan:

// parameter "foo" is not modified
void fna(Foo& foo);

void fnb(const Foo& foo);

Terlepas dari kenyataan bahwa versi terakhir lebih ringkas, itu juga memberikan kontrak yang lebih kuat, dan memungkinkan kompiler membantu Anda mempertahankan niat Anda. Yang pertama tidak melakukan apa pun untuk mencegah fna(Foo&)fungsi memodifikasi parameter yang Anda berikan.

Seperti dalam jawaban @CandiedOrange, Anda dapat menggunakan spasi putih untuk meletakkan kode dan meningkatkan keterbacaan.

Mael
sumber
14

Menghapus constkata kunci menghilangkan keterbacaan karena constmengkomunikasikan informasi kepada pembaca dan kompiler.
Mengurangi panjang kode horizontal itu baik (tidak ada yang suka menggulir ke samping) tetapi ada lebih constdari sekadar teks. Anda dapat menulis ulang:

typedef string str;
typedef MyObject MObj;
void MyClass::myFunction(const MObj& o,const str& s1,const str& s2,const str& s3)

Yang tidak mengubah kontrak tetapi memenuhi kebutuhan untuk mengurangi panjang garis. Sungguh saya akan menganggap potongan di atas kurang dapat dibaca dan akan memilih untuk menggunakan lebih banyak ruang putih seperti yang telah disebutkan dalam jawaban CandiedOrange.

constadalah fungsi dari kode itu sendiri. Anda tidak akan menjadikan fungsi sebagai non-anggota untuk menghapus MyClass::bagian dari deklarasi, jadi jangan hapusconst

Erdrik Ironrose
sumber
4
Saya setuju bahwa cuplikan yang Anda berikan kurang dapat dibaca. Ini memaksa pembaca untuk mencari tahu apa MObjdan apa str, dan tentu saja mengangkat alis. Ini terutama aneh untuk jenis yang namanya Anda sudah memiliki kontrol atas: Misalnya Kenapa kau tidak hanya nama MyObjectseperti MObjuntuk memulai dengan?
Jason C
3

Apakah keterbacaan merupakan alasan yang valid untuk tidak menggunakan const dalam parameter?

Tidak. Mengabaikan constdapat mengubah fungsionalitas, kehilangan perlindungan, constdan berpotensi membuat kode yang kurang efisien.

Apakah dapat dipertahankan untuk menjaga objek parameter tidak berubah secara manual?

Daripada menghabiskan waktu memformat kode secara manual

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
  //
}

Gunakan alat pemformatan otomatis . Tulis fungsi sesuai persyaratan fungsionalnya dan biarkan pemformatan otomatis menangani presentasi. Menyesuaikan pemformatan secara manual tidak seefisien menggunakan pemformatan otomatis dan menggunakan waktu yang disimpan untuk meningkatkan aspek kode lainnya.

void MyClass::myFunction(const MyObject& obj, const string& s1, const string& s2, 
    const string& s3) {
  // 
}
chux - Pasang kembali Monica
sumber
-1

Selama mungkin lebih baik untuk menjaga agar konst terlihat. Ini meningkatkan pemeliharaan kode banyak (tidak ada dugaan untuk melihat apakah metode ini mengubah argumen saya).

Jika saya melihat banyak argumen dalam suatu metode, itu memaksa saya untuk mempertimbangkan pembuatan jaron berbasis proyek (Matriks, Karyawan, Persegi Panjang, Akun) yang akan jauh lebih pendek, lebih mudah dipahami (menghilangkan daftar panjang argumen untuk metode).

pena hitam
sumber
Sepakat. Saya ragu untuk menunjukkannya. Jadi, "kasus ekstrim".
blackpen
@ cmaster Yang mengatakan, kadang-kadang dalam konteks tertentu, dengan programmer tertentu, itu bisa tetap dibaca. Sebagai contoh, dalam kasus yang sangat spesifik dari program sedalam-dalamnya dalam panggilan Windows API, dengan pembaca yang terbiasa dengan lingkungan itu, hal-hal seperti misalnya typedef Point * LPPOINTdan typedef const Point * LPCPOINT, meskipun sangat menjengkelkan, masih membawa makna tersirat, karena konsisten dengan harapan langsung dalam konteks. Tetapi tidak pernah dalam kasus umum; itu hanya pengecualian aneh yang bisa saya pikirkan.
Jason C
1
Ya, ketika saya melihat pertanyaan, "const unsigned long int panjang" muncul di benak saya, tetapi, itu bukan kandidat yang baik untuk mendapatkan manfaat dari menjadi "const" atau "referensi". Typedef memecahkan masalah umum pemendekan nama; tetapi itu tidak terasa seperti desain yang bagus untuk menyembunyikan tujuan dari konstruksi bahasa (seperti "const") di belakangnya.
blackpen